iOS:使用block代码块实现事件处理过程中的回调-阿里云开发者社区

开发者社区> 吞吞吐吐的> 正文

iOS:使用block代码块实现事件处理过程中的回调

简介:
+关注继续查看

block是什么,这里就不多加强调了,它的优点:

第一:执行效率高,速度快

第二:使用起来比代理简单,省却不少代码,增强代码美感

 

有一些小的知识点要强调一下:

第一点:它类似于一个匿名函数,也跟java中的匿名内部类相似,但是,记住,它是一种数据类型,因为它内部是一个结构体,有方法有属性,所以它具有对象的特征;

第二点:在类中声明block为属性时,如果使用assgin修饰,那么它被放到了栈中,方法已过就会被销毁,所以,尽量使用copy作为修饰词,这样一来block就被存放到了堆中,生命周期就会延长,保证block不会被立即销毁;

第三点:要防止循环引用,造成线程死锁,所以,有时需要加上__weak修饰。

第四点:为什么多用copy修饰,而不用strong修饰,这是MRC时期遗留下来的写法习惯,其实用strong也可以修饰,但是尽量用copy。

 

block既可以作为属性,单独赋值然后回调;也可以作为一个方法的参数使用,再进行回调,举例如下,直接代码演示:

我的例子过程大概是:首先用户浏览题库时,点击收藏按钮,弹出收藏界面,用户选择完某一个文件夹后,隐藏收藏界面,提示收藏成功!

例子一:block使用属性单独赋值后回调

这是收藏界面类的回调代码

复制代码
#import <UIKit/UIKit.h>

//声明block,用作选择收藏文件后的回调处理
typedef void (^CollectionBlock)();     //选择文件夹
typedef void (^CompleteHandleBlock)(); //选完之后的处理


@interface KJCollectionView : UITableView
@property (copy,nonatomic)CollectionBlock collectionBlock;
@property (copy,nonatomic)CompleteHandleBlock completeBlock;
-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files;

@end




#import "KJCollectionView.h"
#import "KJMyQueBankFile.h"

@interface KJCollectionView()<UITableViewDataSource,UITableViewDelegate>
@property (strong,nonatomic)NSArray *allFiles;
@end

@implementation KJCollectionView

-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files
{
    self = [super initWithFrame:frame];
    if (self) {
        self.dataSource = self;
        self.delegate = self;
        self.tableHeaderView = [UILabel createLabel:CGRectMake(0, 0, SCREEN_WIDTH, 50) title:@"请选择收藏位置" titleColor:HMColor(13, 195, 176) alignmentType:NSTextAlignmentCenter size:16];
        self.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
        self.allFiles = [NSArray arrayWithArray:files];
        MoveUnderLine(self);
    }
    return self;
}

#pragma mark - block回调,为block属性赋值
-(void)setCollectionBlock:(CollectionBlock)collectionBlock{
    if (_collectionBlock != collectionBlock) {
       _collectionBlock = collectionBlock;
    }
}
-(void)setCompleteBlock:(CompleteHandleBlock)completeBlock{
    if (_completeBlock != completeBlock) {
        _completeBlock = completeBlock;
    }
}


#pragma mark - UITableViewDataSource
#pragma mark - Required

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.allFiles.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *reuseIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc]init];
    }
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"default_true" target:self Done:@selector(chooseFileDone:)];
    cell.imageView.image = [UIImage imageNamed:[self.allFiles[indexPath.row] file_image]];
    cell.textLabel.text = [self.allFiles[indexPath.row] file_Name];
    return cell;
}


#pragma mark - Optional
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50;
}

#pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];

    //回调处理
    _collectionBlock();
    _completeBlock();
}

#pragma mark - 按钮选择文件夹
-(void)chooseFileDone:(UIButton *)btn{
    UITableViewCell *cell = (UITableViewCell *)btn.superview;
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];
    
    //回调处理
    _collectionBlock();
    _completeBlock();
}
@end
复制代码

这是在题库类中给block传递回调处理的代码:直接通过属性赋值

复制代码
#pragma mark - 点击收藏按钮时的代理方法
/**
 *  收藏作业
 *  @param indexPath     当前cell中选择按钮选中后的cell
 *  @param btn           收藏按钮
 *  @param collectionTag 当前cell中收藏按钮的tag
 */
-(void)finishedClickedCollectionFileIndexPath:(NSIndexPath *)indexPath CollectionBtn:(UIButton *)btn{
    
    //创建收藏文件夹视图和蒙版视图
    self.collectionView = [[KJCollectionView alloc]initWithFrame:CGRectMake(0, 0, 260, 200) withFiles:self.filesArrayM];
    self.collectionView.layer.cornerRadius = 3.0;
    self.collectionView.layer.masksToBounds = YES;
    self.collectionView.center = [UIApplication sharedApplication].keyWindow.center;
    self.coverView = [[UIView alloc]initWithFrame:self.view.bounds];
    self.coverView.backgroundColor = HMColorRGBA(51, 51, 51, 0.3);
    [self.view addSubview:self.collectionView];
    [self.view addSubview:self.coverView];
    [self.view insertSubview:self.collectionView aboveSubview:self.coverView];
    __weak typeof(self) weakSelf = self;
    
 
   //为选择文件的block赋值
    self.collectionView.collectionBlock = ^(){
        //取出收藏字典
        KJChooseHomeworkDicM *checkBtnDicManager = [KJChooseHomeworkDicM sharedCheckBtnDicMManager];
        [checkBtnDicManager.collectionDicM setObject:indexPath forKey:indexPath];
        [btn setSelected:YES];
        //获取作业模型
        KJLog(@"clickedCollection:%@",[weakSelf.homeworkCellFrames[indexPath.row] defaultFH]);
        
    };
    
   //为选完文件后的block赋值
    self.collectionView.completeBlock = ^(){
        [MBProgressHUD showSuccess:@"收藏成功"];
        //移除收藏文件夹视图和蒙版视图
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf.collectionView removeFromSuperview];
            [weakSelf.coverView removeFromSuperview];
            [weakSelf setCollectionView:nil];
            [weakSelf setCoverView:nil];
        });
    };
}
复制代码

例子二:block作为方法的参数赋值后再进行回调

这是收藏界面类的回调代码

复制代码
#import <UIKit/UIKit.h>

//声明block,用作选择收藏文件后的回调处理
typedef void (^CollectionBlock)();     //选择文件夹
typedef void (^CompleteHandleBlock)(); //选完之后的处理


@interface KJCollectionView : UITableView
@property (copy,nonatomic)CollectionBlock collectionBlock;
@property (copy,nonatomic)CompleteHandleBlock completeBlock;
-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files;

//声明一个方法
-(void)chooseFile:(CollectionBlock )collectionBlock compeleteChooseBlock:(CompleteHandleBlock)completeBlock;
@end


//  Created by mac on 16/5/20.
//  Copyright © 2016年 mac. All rights reserved.
#import "KJCollectionView.h"
#import "KJMyQueBankFile.h"

@interface KJCollectionView()<UITableViewDataSource,UITableViewDelegate>
@property (strong,nonatomic)NSArray *allFiles;
@end

@implementation KJCollectionView

-(instancetype)initWithFrame:(CGRect)frame withFiles:(NSArray *)files
{
    self = [super initWithFrame:frame];
    if (self) {
        self.dataSource = self;
        self.delegate = self;
        self.tableHeaderView = [UILabel createLabel:CGRectMake(0, 0, SCREEN_WIDTH, 50) title:@"请选择收藏位置" titleColor:HMColor(13, 195, 176) alignmentType:NSTextAlignmentCenter size:16];
        self.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
        self.allFiles = [NSArray arrayWithArray:files];
        MoveUnderLine(self);
    }
    return self;
}

#pragma mark - block回调,通过方法为block属性赋值
-(void)chooseFile:(CollectionBlock )collectionBlock compeleteChooseBlock:(CompleteHandleBlock)completeBlock{
    
    if (_collectionBlock != collectionBlock) {
        _collectionBlock = collectionBlock;
    }
    if (_completeBlock != completeBlock) {
        _completeBlock = completeBlock;
    }
}

#pragma mark - UITableViewDataSource
#pragma mark - Required

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.allFiles.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *reuseIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc]init];
    }
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"default_true" target:self Done:@selector(chooseFileDone:)];
    cell.imageView.image = [UIImage imageNamed:[self.allFiles[indexPath.row] file_image]];
    cell.textLabel.text = [self.allFiles[indexPath.row] file_Name];
    return cell;
}


#pragma mark - Optional
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50;
}

#pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];

    //回调处理
    _collectionBlock();
    _completeBlock();
}

#pragma mark - 按钮选择文件夹
-(void)chooseFileDone:(UIButton *)btn{
    UITableViewCell *cell = (UITableViewCell *)btn.superview;
    cell.accessoryView = [UIButton createButton:CGRectMake(0, 0, 30, 30) imageName:@"selected_ture" target:nil Done:nil];
    
    //回调处理
    _collectionBlock();
    _completeBlock();
}
@end
复制代码

这是在题库类中给block传递回调处理的代码:直接将要赋值的block写入到方法中

复制代码
#pragma mark - 点击收藏按钮时的代理方法
/**
 *  收藏作业
 *  @param indexPath     当前cell中选择按钮选中后的cell
 *  @param btn           收藏按钮
 *  @param collectionTag 当前cell中收藏按钮的tag
 */
-(void)finishedClickedCollectionFileIndexPath:(NSIndexPath *)indexPath CollectionBtn:(UIButton *)btn{
    
    //创建收藏文件夹视图和蒙版视图
    self.collectionView = [[KJCollectionView alloc]initWithFrame:CGRectMake(0, 0, 260, 200) withFiles:self.filesArrayM];
    self.collectionView.layer.cornerRadius = 3.0;
    self.collectionView.layer.masksToBounds = YES;
    self.collectionView.center = [UIApplication sharedApplication].keyWindow.center;
    self.coverView = [[UIView alloc]initWithFrame:self.view.bounds];
    self.coverView.backgroundColor = HMColorRGBA(51, 51, 51, 0.3);
    [self.view addSubview:self.collectionView];
    [self.view addSubview:self.coverView];
    [self.view insertSubview:self.collectionView aboveSubview:self.coverView];
    __weak typeof(self) weakSelf = self;

//把block放入方法中 [self.collectionView chooseFile:
^{ //取出收藏字典 KJChooseHomeworkDicM *checkBtnDicManager = [KJChooseHomeworkDicM sharedCheckBtnDicMManager]; [checkBtnDicManager.collectionDicM setObject:indexPath forKey:indexPath]; [btn setSelected:YES]; [MBProgressHUD showSuccess:@"收藏成功"]; //获取作业模型 KJLog(@"clickedCollection:%@",[weakSelf.homeworkCellFrames[indexPath.row] defaultFH]); } compeleteChooseBlock:^{ //移除收藏文件夹视图和蒙版视图 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [MBProgressHUD hideHUD]; [weakSelf.collectionView removeFromSuperview]; [weakSelf.coverView removeFromSuperview]; [weakSelf setCollectionView:nil]; [weakSelf setCoverView:nil]; }); }]; }
复制代码

 

上面两种演示截图达到的效果是一样的:

点击题库中的收藏                     选择文件夹收藏      

    

显示收藏成功                      移除文件夹视图

    

 

本人原创,转载须注明出处,谢谢!

程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/5512618.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
飞天加速计划初体验
最近因需要使用云服务器来学习,老师让我们用这个阿里云类进行相关的学习,让我们先进行免费的使用进行学习,慢慢了解,毕竟对于首次接触的事物都是了解为主不会投入大量资金。阿里云平台有详细的教程,让初学者能十分轻松的进行学习。飞天加速计划是个好想法,可以让我们这些学生进行学习,制作出自己的网站。让我在暑假对计算机有了浓厚的兴趣,于是在阿里云我选择了飞天加速计划,学习大数据和服务器啥的,让自己get到更多的知识~
7 0
我的无影云电脑初体验
最近看到阿里云开发者社区有无影云电脑的体验活动,遂报名体验。 由于在阿里云开发者社区是专家博主,有幸获得一年的 4核 8G 无影云电脑的体验机会。 试用了几天,下面从无影云电脑的用户群体、无影云电脑的使用场景,我的使用感受,目前还存在的问题等方面,简单谈谈自己的感受。
14 0
Kubernetes + Spring Cloud 集成链路追踪 SkyWalking
分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。 提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
5 0
从零到一上手玩转云服务器
从零到一上手玩转云服务器
14 0
大学生第一次使用阿里云的感受
阿里云、服务器、tomcat、xshell
10 0
06_spring_ 依赖注入| 学习笔记
快速学习 06_spring_ 依赖注入
11 0
05_spring_ 配置文件| 学习笔记
快速学习05_spring_ 配置文件
6 0
文件查找和压缩 | 学习笔记
快速学习文件查找和压缩。
12 0
04_spring_ioc 创建对象的方式| 学习笔记
快速学习 04_spring_ioc 创建对象的方式
5 0
初始ECS
物联网学习的硬性需求,我们需要搭建一台自己的服务器,在不断查找资料和方法后,获知阿里云ECS云服务器有学生体验资格,继而我将利用ECS云服务器搭建一个自己的EMQX服务器端。
17 0
4852
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载