block中weakself、strongself 的引用规范

项目中的宏定义
<pre>

define kSelfWeak __weak typeof(self) weakSelf = self

define kSelfStrong __strong typeof(weakSelf) strongSelf = weakSelf

</pre>

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

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

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

  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执行结束会由系统回收从而打破循环引用

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容