ios 中的程序块(Block)
Block具有将临时函数体创建为表达式的优势。Apple文档中指出:
Block是符合如下要求的匿名内联的代码集:
- 和函数一样具有一个指定类型的参数列表
- 有一个可以推导或声明的返回值类型
- 可以从它被定义的词义范围中捕捉状态
- 可以在需要的时候改变词义范围的状态
- 可以和相同的词义范围中定义的其他的Block共享更改的可能。
- 可以在词义范围(堆栈帧)被销毁后继续共享和修改该词义范围(堆栈帧)的状态。
Block是一个自包含的小代码段,封装了用于遍历(线性遍历)或者回调,可以并发执行的任务单元。
__block int myCount = 0; int (^myBlock)(int a,int b) = ^(int a,int b){ myCount = a+b; return myCount; }; NSLog(@"myBlock = %d",myBlock(1,2));
1 int (^myBlock)(int a,int b); 2 3 myBlock = ^(int a,int b){ 4 myCount = a+b; 5 return myCount; 6 };
1 int jg = ^(int a){ return a*a; } (3); 2 NSLog(@"jg = %d",jg);
後面小括號裡的3 會被當成a的輸入值,然後經由Block輸出3*3 = 9指定給result這個變數。
因為block也是繼承自NSObject,所以其生命周期和記憶體的管理也就非常之重要。
block一開始都是被放到stack裡,換句話說其生命周期隨著method或function結束就會被回收,和一般變數的生命周期一樣。
關於記憶體的管理請遵循這幾個要點
1. block pointer的實體會在method或function結束後就會被清掉
2. 如果要保存block pointer的實體要用-copy指令,這樣block pointer就會被放到heap裡
2.1 block 主體裡用到的block variable 也會被搬到heap 而有新的記憶體位置,且一並更新有用到這個block variable 的block都指到新的位置
2.2 一般的variable值會被copy
2.3 如果主體裡用到的variable是object的話,此object會被retain, block release時也會被release
2.4 __block variable 裡用到的object是不會被retain的