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(, , SCREEN_WIDTH, ) title:@"请选择收藏位置" titleColor:HMColor(, , ) alignmentType:NSTextAlignmentCenter size:];
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(, , , ) 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 ;
} #pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = [UIButton createButton:CGRectMake(, , , ) 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(, , , ) 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(, , , ) 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(, , , 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(, , SCREEN_WIDTH, ) title:@"请选择收藏位置" titleColor:HMColor(, , ) alignmentType:NSTextAlignmentCenter size:];
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(, , , ) 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 ;
} #pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = [UIButton createButton:CGRectMake(, , , ) 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(, , , ) 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(, , , ) 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(, , , 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];
});
}];
}
上面两种演示截图达到的效果是一样的:
点击题库中的收藏 选择文件夹收藏

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

本人原创,转载须注明出处,谢谢!
iOS:使用block代码块实现事件处理过程中的回调的更多相关文章
- iOS - OC Block 代码块
前言 Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的,类似于一个 ...
- block(代码块)的介绍以及使用方法和变量之间的关系
http://blog.csdn.net/menxu_work/article/details/8762848 block(代码块)的介绍以及使用方法和变量之间的关系 block(代码块)的介绍以及使 ...
- ios开发 block语句块
ios开发 block语句块 1.block 理解为匿名函数 2.block变量的定义 //定义block变量,^表示定义block //技巧:函数名左右加括号,在函数名前面在加^ void (^bl ...
- IOS开发之----代码块的使用(二)
iOS4引入了一个新特性,支持代码块的使用,这将从根本上改变你的编程方式.代码块是对C语言的一个扩展,因此在Objective-C中完全支持.如果你学过Ruby,Python或Lisp编程语言,那么你 ...
- block代码块介绍
关于block的简单介绍 什么是block? Block是C语言的一个语法特性,同时也是C语言的运行时特性,它很像C中的函数指针,因为你可以像使用函数指针一样的去使用block对象:它也很像C++中的 ...
- Block代码块中使用局部变量注意点
第一次写代码遇到报这个错,实在是想不通为什么,按常理应该是不会有问题,报错的呀??纠结了一会之后只好仔细查看报错原因咯,原来是: 当我们在block代码块中使用局部变量时,就会很容易出现如图的错误. ...
- eclipse实现代码块折叠-类似于VS中的#region……#endregion
背 景 刚才在写代码的时候,写了十几行可以说是重复的代码: 如果整个方法或类中代码多了,感觉它们太TM占地方了,给读者在阅读代码上造成很大的困难,于是想到能不能把他们“浓缩”成一行,脑子里第一个闪现出 ...
- 【玩转Eclipse】——eclipse实现代码块折叠-类似于VS中的#region……#endregion
[玩转Eclipse]——eclipse实现代码块折叠-类似于VS中的#region……#endregion http://www.cnblogs.com/Micheal-G/articles/507 ...
- IOS学习4——block代码块
本文转载自:iOS开发-由浅至深学习block 一.关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调.这不免让我们想 ...
随机推荐
- MiCode 40: 找小“3”
题目链接 这道题真的是zjb恶心, 看其起来像是个数位dp, 然而我并不会数位dp.然后就xjb乱写了个雷类似于动态规划的玩意, 然后调出了\(9\times 9 = 81\)种Bug, 终于过了. ...
- linux命令(32):free命令
1.显示内存使用情况:free free –g free –m 2.以总和的形式显示内存的使用信息: free -t 3.周期性的查询内存使用信息:free -s 10
- mysql 库操作、存储引擎、表操作
阅读目录 库操作 存储引擎 什么是存储引擎 mysql支持的存储引擎 如何使用存储引擎 表操作 创建表 查看表结构 修改表ALTER TABLE 复制表 删除表 数据类型 表完整性约束 回到顶部 一. ...
- Linux 基础——ls 命令
第二天,继续学习Linux命令... 一.查看文件和目录列表的命令 ls:显示当前目录下的文件和目录,但是不会显示隐藏的文件和目录. ls -a:显示当前目录下的所有文件和目录. ls -l:显示当前 ...
- GITHUB个人博客搭建-Pelican 在Windows环境下的安装及配置
GITHUB个人博客搭建-Pelican 在Windows环境下的安装及配置 前言 此篇博客主要为Pelican在Windows平台下的配置安装所写,在此过程中主要参考资料烟雨林博客.poem_of_ ...
- Run Rancher server on windows
软件环境:WIN 10 一.首先安装Docker for Windows,Cmder(我用这个执行Docker 命令) 二.右键右下角Docker 图标--> Daemon ,在Registry ...
- Hadoop 学习【一】 安装部署
目标:测试Hadoop的集群安装 参考文档: [1]http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/Sin ...
- Mybatis框架-1
1.Mybatis框架: Mybatis是一个半自动的对象关系映射(ORM),实现结果集的自动封装,sql写到配置文件中: Mybatis使用的是DTD约束. 2.Mybatis模块调用: 3.Sql ...
- 51使用while进行延时的问题
上周写了一个简单的IO口翻转的程序,但是很奇怪,在FPGA板子上怎么也跑不起来. 后面发现问题可能出在延时函数上. void Delay(unsigned char t) { while(--t); ...
- 洛谷——P1890 gcd区间
P1890 gcd区间 题目描述 给定一行n个正整数a[1]..a[n]. m次询问,每次询问给定一个区间[L,R],输出a[L]..a[R]的最大公因数. 输入输出格式 输入格式: 第一行两个整数n ...