block学习笔记
1. 创建block变量的并使用:
1 typedef int (^BLK)(int); // 定义block类型 2 3 - (void)doSomething 4 { 5 BLK foo = ^(int a){ return a*a; }; // 创建block变量 6 printf("%d", foo(4)); // 直接调用block 7 }
2. 不创建block变量,直接创建内联block,比如调用一个对数组进行排序的函数:
1 - (void)doSomething 2 { 3 NSArray *array = nil; 4 [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 5 // do comparation 6 return NSOrderedSame; 7 }]; 8 }
3. block可以修改相同作用域内的变量,只要用__block来修饰某变量,在随后作用域中调用的block可以改变其值。
4. 一个block就是一个匿名的内联代码集合体,和函数一样有参数列表、返回类型。
5. block可以捕获它声明所在作用域的状态,可选地修改这些状态。相同作用域内声明的block共享这些状态。
6. 同一作用域中声明的block,在栈帧被销毁后持续共享和更改此作用域中的状态。
7. 尽管block在纯C和C++上面可用,但一个block也同样是一个Objective-C的对象。
8. 使用block代替传统回调函数可以使你在调用的地方编写回调函数要执行的操作,由于block可以直接访问局部变量,省去了给回调函数传一堆上下文信息的麻烦。
9. block还支持可变参数。一个没有使用任何参数的block必须在参数列表上面用void标明。
10. block中可以访问全局变量、全局静态变量、局部静态变量、局部变量、参数。
11. __block变量不能是可变长的数组,也不能是包含可变长数组的数据结构。
12. __block变量不会被retain。
13. 通常不需要拷贝block,当需要block在被声明的作用域销毁后能继续使用的话,就需要拷贝到堆上去。
14. 当拷贝一个block时,任何在该block中对其它block的引用都会在需要的时候被拷贝。
15. 拷贝一个栈上block时,会得到一个新的block;拷贝一个堆上block时,只是增加了该block的引用计数。
16. block被拷贝的时候会对其引用的对象进行retain操作。引用self、引用成员对象或调用成员函数会对self进行retain操作,成员对象无影响。这里关键是被拷贝的时候,如果block没有被拷贝则无此。
17. 引用成员变量会对self进行retain,而如果在声明block之前声明一个局部的变量,将成员变量赋值给这个局部变量,再在block中访问这个局部变量则不会对self进行retain,但是局部变量的值不会跟成员变量的值一起变化,局部变量的值固定为创建时候的值,即当后来如果改变成员变量的值,再调用block,也不会用到新的值。