-----<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!
-------
oc的block
- Block是c语言的,所以在没有参数时,定义的参数不能省略;但实现的参数可以省略;
- Block是oc的一种数据类型;
- block是预先准备好的代码,在需要的时候执行;
- Blcok速记方法:inlineBlock(xcode在代码块中预定义的),但是一定要能自己写出来;
- 定义block类型速记方法:typedefBlock,例如:
typedef void(^eBlock)(); eBlock myDemo(){ eBlock myBlock = ^{ NSLog(@"MyBlock"); }; return myBlock; };
block的格式
- 格式一: 完整格式
返回类型 (^blockName)(参数列表) = ^返回类型(参数列表){ //代码实现;};
实例:
int(^sumBlock)(int,int) = ^int(int x ,int y ) { return x + y; }; -
格式二:缩写格式
返回类型:void(^blockName)(参数列表) = ^(参数列表){ //代码实现;};
实例:
void(^sumBlock1)(int,int) = ^(int x,int y){ NSLog(@"%zd",x+y); }; -
格式三: 缩写格式2
void(^blockName)() = ^{ //代码实现;};
实例:
void(^MyBlock)() = ^{NSLog(@"My block");};
block的反向传值和与代理的比较
反向传值思路:A <-- B,B控制器传值给A,思路分析:
1.在B控制器中定义一个block属性,并在需要的时候执行block;
2.在A中,跳转的时候给B控制器的block设置数值,在block中给当前的属性设值。
block与代理的比较:
1. block:调用方准备块代码;被调用方:定义块代码属性(为了传递块代码),在需要的时候执行;
2. 代理:当代理的三部曲和委托的三部曲,比较费劲。
3. block在传值的时候,同样需要判断是否设置,和代理判断代理执行方法一样。
4. block与代理的选择:blcok适合比较小巧的“回调”,通常1~3回调方法比较合适;如果回调的多,使用代理就比较合适了;使用大力可以指定协议方法是否必须实现。
如何使用block
- 想参数一样传递:当参数和普通类型是一样的,需要有类型和返回值,也就是block的前半部分
block使用范围:
- 遍历数组或字典
- 数组排序
- 视图动画
- 结束回调
- 错误处理
- 多线程
- ……
block使用注意:
- 在block中,引用外部变量会做一次copy,不允许在block内部修改外部变量的值;如果后续再修改外部变量的值,不会影响内部的变化;
- 如果内部直接修改外部数值,会影响代码的阅读和维护;
- 如果使用了__block修饰符,在定义block的时候,外部的地址会同时改变;
- block作为成员变量的时候,要使用的copy。
block的陷阱
- 反向传值的话,会对B控制器copy,copy的话会增加B的强引用,导致循环引用;
- 陷阱测试:通常可以在B控制器中实现delloc方法进行测试;
- 解决:使用__weak修饰符,改成弱引用;
- 如果在block中出现了self,一定要特别小心,很可能会出现循环引用。