跳过正文

block 中 strongself剖析

·2 分钟
目录

前言
#

解决内存提前释放,与weakself 相对。在使用的时候依然还存在。

weakself
#

首先 block 使用 weakself 来打破循环引用。新建的 weakself 指针 指向 self。 同时用 weak 来修饰 weakself。

__weak typeof(self) weakself = self;

实现代码中的解析

  • 其中 typeof(self)返回的是这个 self 对象的类型。
  • 这个时候可以在 block 里面 weakself。

strongself
#

strongself 是强引用指针,也就是引用加一。参与 self 的内存管理,保证了 block 中 self 一直存在, self 使用必须等到 block 运行完,这个强引用消失,self 才可以释放。如果用 weakself 在 block 里面执行一些 code,self 本身的内存管理 在外界决定的,self 计数可能为 0.导致 block 中有些 code 不执行。

故为了保证 self 在 block 执行过程里一直存在,对他强引用 strongSelf。 实现代码

__strong typeof(weakSelf) strongSelf = weakSelf;

方便使用的方法
#

宏定义 weakify与strongify,使用 @weakify(self);@strongify(self);

#ifndef weakify
    #if DEBUG
        #if __has_feature(objc_arc)
        #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
        #else
        #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
        #endif
    #else
        #if __has_feature(objc_arc)
        #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
        #else
        #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
        #endif
    #endif
#endif

#ifndef strongify
    #if DEBUG
        #if __has_feature(objc_arc)
        #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
        #else
        #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
        #endif
    #else
        #if __has_feature(objc_arc)
        #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
        #else
        #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
        #endif
    #endif
#endif

总结
#

  • 外部新建 weaself 指针,内部新建 strongself 指针 解决了循环引用的问题有解决了 self 被提前换释放的问题。

  • 关于 Masonry ,它内部根本没有捕获变量 self,进入 block 的是 testButton,所以执行完毕后,block 会被销毁,没有形成环。所以,没有引起循环依赖。

参考
#

https://halfrost.com/ios_block_retain_circle/