block中weakself、strongself 的引用规范

项目中的宏定义

define kSelfWeak __weak typeof(self) weakSelf = self

define kSelfStrong __strong typeof(weakSelf) strongSelf = weakSelf

正常我们在使用block时会写出如下的代码:

  • (void)function{
    kSelfWeak; //创建一个指向当前对象的弱引用
    [teseObject callFunc:^{
    kSelfStrong; //block内部定义一个指向当前对象的强引用
    [strongself callFunc_1:....];
    [strongself callFunc_2:....];
    ....
    }];
    }

现在我们来带着问题分析一下上面的这个代码:

  1. 可不可以直接使用self?
    不可以。因为这样block会强持有self对象,造成循环引用,从而导致内存泄露。

  2. 可不可以直接使用weakself?
    看情况。由于weakself不会持有对象,因此不会造成循环引用的问题,但是使用weakself却会造成block执行不一致问题,试想一下上面的代码,当调用“callFunc_1”的时候weakself是有效的,但是当调用“callFunc_2”的时候weakself可能已经是nil了,这样就造成了block内执行不一致从而导致意想不到的结果

  3. 循环引用是不是都是坏人?
    答案是否定的。当block开始执行的时候,strongself会去取self对象的值,如果此时self已经为nil,那么整个block执行期间strongself都是nil,如果self有效那么strongself就是利用了循环引用的特性保证了在block执行的时候self对象不会被析构,保证block执行的一致性。其实我们在编写业务代码的时候(很多第三方开源类库)中会利用到循环引用的这一特性来保证block中引用的对象在block执行的时候依然有效,但是切忌使用这样黑魔法的时候要在block执行结束后打破循环引用。由于strongself是block内部定义的变量,在block执行结束会由系统回收从而打破循环引用


总结:使用strongself可以消除循环引用带来的内存泄漏,也可以保证block执行过程中的一致性。所以正常的业务代码我们都会使用上面的标准方式编写,只有特殊的情况才会利用block的特性写一些黑魔法的代码。

更多原理:http://www.jianshu.com/p/a5dd014edb13

你可能感兴趣的:(block中weakself、strongself 的引用规范)