OC 3大回调模式使用总结(三)block回调
block 又称 代码块,闭包等
是一个匿名的函数,它可以当做一个对象来使用,只不过这个对象很特殊,是一段代码,他可以保存你写的一段预备性质代码,待某个不确定的事件发生时再调用;事件发生时,它可能会给你传递一些状态参数(回传),来方便你的使用
block常用类型(可以看做一个匿名函数的类型):
typedef int(^Add)(int,int);//定义一个block类型 typedef void(^Logg)(NSString *);//有一个参数,但是没有返回值的 typedef void(^FFF)(void);//没有参数也没有返回值
block外部变量(可以被block引用)
NSString *s1 = @"你好外部变量1"; __block int ccc = 2;//__block修饰的变量可以在代码块内部改变,否则是不可以改变的
使用上述的3中block类型,定义3个block变量,可以当做函数使用
Add aa = ^(int a,int b)//定义一个block变量,变量的值是一段代码 { NSLog(@"s1 = %@",s1);//捕获外部变量 NSLog(@"ccc = %d",ccc); ccc++;//默认外部变量是只读的,除非加上__block return a+b; }; NSLog(@"%d",aa(1,2));//调用aa 代码块
Logg lo = ^(NSString *str) { NSLog(@"打印字符串!%@",str); }; lo(@"没有返回值的block测试!");
FFF f = ^(){NSLog(@"s1 = %@",s1);ccc++;}; f();//没有参数的block使用
block的使用场景:
1.网络请求的回调 2.封装自定义的组件 3.反向传值 4.其他
block的特点:block中可以捕获其他对象的属性和方法,作用域很大;我们在(3)中进行说明
(1)如果你使用过AFNetworking或者ASIHttpRequest你不会对第1种使用场景产生任何疑问,对于网络请求的成功或者失败的操作,都是需要时间的,都是异步的操作;所以,你需要提前写好操作代码,待某个状态到达的时候会则自动调用这段代码;例如你提前写好网络请求成功之后的block块,该block可能包含一些参数,这些参数是请求成功或者失败之后的参数,可以让你对这些参数进行处理
例如AFNetworking的使用,对于成功或者失败之后的处理都是使用了block
成功之后的执行的block
success:^(AFHTTPRequestOperation *operation, id responseObject) {}
失败之后执行的block
failure:^(AFHTTPRequestOperation *operation, NSError *error) {//失败之后的block块 }
/*
* 开启一个异步网络请求,成功或失败后,会执行你写的代码
*/
AFHTTPRequestOperation *op = [self.afMannager GET:url parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {//成功后其返回成功的状态参数,供你使用 NSArray *arr = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];//JSON解析 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { //失败之后的block块,处理失败操作 }]; op.responseSerializer = [AFHTTPResponseSerializer serializer]; [op start];//开始请求
(2)你也可以自己封装一些组件,然后给外界一些处理事件的接口,这个时候你也可以使用block回调模式;只需要外界传入他的处理代码,那么这个组件在达到这个状态的时候,就会自动调用你写的代码.
(3)反向传值,例如两个界面A,B;点击A界面上的按钮跳到B 编辑界面,B编辑界面在返回时需要传给A界面一些字符串,这个过程是反向传值;这个时候我们可以使用block模式来实现.
在A类中,我们可以预设B界面返回时的代码,即使用block,注意到在B返回时,这个事件需要汇报B自身的状态,即B要汇报一些有用的参数(字符串),那么block需要有一个参数,该参数就是B返回时传来的
代码示例:
A中给B预设返回时的代码块,也就是说B 的代码块获得了A的属性和方法,B在状态改变时会调用该block改变A A.m [B setTapSaveBlock:^(NSString *str) { [self.btn_Hobby setTitle:str forState:UIControlStateNormal]; }]; [self.navigationController pushViewController:B animated:YES];//从A 推到B 界面
描述: A推到B界面之前,首先给B设置返回时的代码,该代码用于返回B的参数str,该代码用于调用A的某些属性或者方法
效果:在B的block控制了A的某些属性和方法,且B能汇报自己的状态给A(也就是block的参数);A的属性拿到B的参数后可能将该参数用于配置A,从而达到了反向传值的目的,把B的值传给了A
效果演示:
A界面:
点击我的昵称,签名,兴趣爱好会推到一个新的界面B:
B 界面:
在B编辑完成,之后需要把最新的文本,回传给A; 也就是关闭 B界面时,A上需要显示B传给A的 字符串,这个过程就包含由B到A的反向传值过程
更多相关文章:http://blog.csdn.net/yangbingbinga/article/category/2437601