美文网首页
用RunTime给Category添加weak属性

用RunTime给Category添加weak属性

作者: _moses | 来源:发表于2019-05-11 23:24 被阅读0次

    我们知道用RunTime给Category添加属性的时候,系统只提供了下面五个枚举

    OBJC_ASSOCIATION_ASSIGN = 0, 
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, 
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, 
    OBJC_ASSOCIATION_RETAIN = 01401,  
    OBJC_ASSOCIATION_COPY = 01403,    
    

    我们还知道assign和weak的区别就在于引用计数为0的时候weak会自动置空,而assign不会。
    那我们是不是可以将assign改造成weak呢?

    思路大概是这样的:新建一个中间类,然后让这个assign属性强引用(retain)这个中间类的对象,然后再让这个中间对象弱引用(weak)self,然后在中间对象销毁的时候将assign对象置空即可。

    废话少说,直接上代码

    @interface UIView (MSCategory)
    
    @property (nonatomic, weak) UIView *test;
    
    @end
    
    @implementation UIView (MSCategory)
    
    - (void)setTest:(UIView *)test {
        SEL sel = @selector(test);
        objc_setAssociatedObject(self, sel, test, OBJC_ASSOCIATION_ASSIGN); // self持有test
        if (test) {
            // MSRuntimeWeakPropertyMiddleModel就是那个中间类
            MSRuntimeWeakPropertyMiddleModel *model = [MSRuntimeWeakPropertyMiddleModel new];
            model.obj = self; // model持有self
            model.property = NSStringFromSelector(sel);
            objc_setAssociatedObject(test, sel, model, OBJC_ASSOCIATION_RETAIN_NONATOMIC); // test持有model
        }
    }
    
    - (UIView *)test {
        return objc_getAssociatedObject(self, @selector(test));
    }
    
    @end
    
    @interface MSRuntimeWeakPropertyMiddleModel : NSObject
    
    @property (nonatomic, weak) id obj; /**< 宿主对象 */
    @property (nonatomic, copy) NSString *property; /**< 属性名 */
    
    @end
    
    @ implementation MSRuntimeWeakPropertyMiddleModel
    
    - (void)dealloc {
        [self.obj setValue:nil forKey:self.property];
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:用RunTime给Category添加weak属性

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