2017 iOS跳槽宝典

面试篇(三):Block 用过吗?

2016-12-21  本文已影响50人  L柠_檬

如下 例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();

无 __block:编译时只是拿到了变量 i 的值,而不是持有i,当执行 i ++, block 里面与 i 没有任何关系了,所以不会改变 block 里值。

有 __block:编译时block代码块会产生一个结构体,持有变量 i , 修改 i 的值,可以改变block 里的值。

原理:

首先要确定代码的执行 顺序

屏幕快照 2016-12-21 下午2.59.25.png

当执行 步骤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
上一篇下一篇

猜你喜欢

热点阅读