如下 例1 和 例2 的区别?
例1:
__block int i = 4;
void (^block)(void) = ^(){
printf("i = %d", i);
};
i++;
block();
例2:
int i = 4;
void (^block)(void) = ^(){
printf("i = %d", i);
};
i++;
block();
- printf 结果不同:例1结果( 5 )、例2结果 ( 4 ) ;
- __block 有无导致结果不同
无 __block:编译时只是拿到了变量 i 的值,而不是持有i,当执行 i ++, block 里面与 i 没有任何关系了,所以不会改变 block 里值。
有 __block:编译时block代码块会产生一个结构体,持有变量 i , 修改 i 的值,可以改变block 里的值。
原理:
首先要确定代码的执行 顺序
当执行 步骤3 i++的时候,步骤2 已经编译完成。变量前面加上__block时,在编译的时候就会生成一个结构体,结构体持有变量 i , 当执行i ++ ,结构体中的 i 进行++运算。而例2中 block代码块 并没持有变量 i ,所以无论如何修改都没用。
使用block时什么情况会发生引用循环,如何解决?
一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。
举例:封装一个SudokuView,SudokuView 的点击事件通过block回调。当在Controller 中通过属性创建全局 SudokuView 对象,那么self. sudokuView 代码块里面存在self 的时候就会产生循环引用。
解决方案:
#define WEAKSELF() __weak __typeof(&*self)weakSelf = self
#define STRONGSELF() __strong typeof(weakSelf)strongSelf = weakSelf
#define BLOCKSELF() __block __typeof(&*self)blockSelf = self