美文网首页
Block循环引用之weak&strong

Block循环引用之weak&strong

作者: 阳明先生1208 | 来源:发表于2016-09-07 10:14 被阅读21次

    在ARC环境下,我们会使用_weak修饰符来修饰一个变量防止其在block中被循环引用,特殊情况下还会在block中使用_strong修饰符来修饰这个变量如下

    __weak __typeof(self)weakSelf = self;
    AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
      __strong __typeof(weakSelf)strongSelf = weakSelf;
      strongSelf.networkReachabilityStatus = status;
      if (strongSelf.networkReachabilityStatusBlock) {
        strongSelf.networkReachabilityStatusBlock(status);
      }
    };
    

    这是因为在block中调用self会引起循环引用,同时在block中需要对weakSelf进行strong操作,保证self不会被释放,当block执行完会自动释放该strongSelf。但实际上strong是为了防止野指针,而block里大部分是用weakSelf访问self的属性,而不是局部变量,我们也不可能主动释放self,这样看来就没有strong的必要了当然不排除有特殊情况。
    除开上面这种一般写法,我们看看YYKit中是怎么使用weak&strong:

    #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
    
    /**
     Example:
        @weakify(self)
        [self doSomething^{
            @strongify(self)
            if (!self) return;
            ...
        }];
     */
    

    还有来自libextobjc的这种写法:

    #define weakify(...) \\
        autoreleasepool {} \\
        metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
    
    #define strongify(...) \\
        try {} @finally {} \\
        _Pragma("clang diagnostic push") \\
        _Pragma("clang diagnostic ignored \\"-Wshadow\\"") \\
        metamacro_foreach(rac_strongify_,, __VA_ARGS__) \\
        _Pragma("clang diagnostic pop")
    

    其中细节可以参考这篇文章http://www.jianshu.com/p/3d6c4416db5e

    相关文章

      网友评论

          本文标题:Block循环引用之weak&strong

          本文链接:https://www.haomeiwen.com/subject/obrjettx.html