美文网首页
iOS类别Catagory添加weak属性

iOS类别Catagory添加weak属性

作者: OOOlive | 来源:发表于2019-06-12 15:21 被阅读0次

开发过程中发现,一个控制器pop后不会走dealloc方法,除了一些常见的原因,还有个不容易被发现的问题 —— 该控制器中使用到某个类的Catagory,而又为Catagory添加了一个属性强引用当前控制器。

但我们都知道在使用runtime关联对象时,只有一下几个属性:

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

如果我们使用OBJC_ASSOCIATION_RETAIN_NONATOMIC来修饰这个属性,相当于strong,就会造成循环引用导致当前视图无法被释放。

  • 错误代码:
objc_setAssociatedObject(self, &showInVC, [self getCurrentVC], OBJC_ASSOCIATION_RETAIN_NONATOMIC);

UIViewController *currentVC = objc_getAssociatedObject(self, &showInVC);

因此需要给类别Catagory添加weak属性解决这个问题!

Catagory添加Weak属性

  1. 新建一个类,用于包裹weak对象

由于 objc_AssociationPolicy没有weak属性,所有使用object包裹一层

@interface GLCatagoryWeakWrapper : NSObject
@property (nonatomic, weak) id weakObj;
@end

@implementation GLCatagoryWeakWrapper
@end
  1. 在Catagory中使用
- (void)setWeakCurrentVC {
    GLCatagoryWeakWrapper *wrapper = [[GLCatagoryWeakWrapper alloc] init];
    wrapper.weakObj = [self getCurrentVC];
    objc_setAssociatedObject(self, @selector(getWeakCurrentVC), wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)getWeakCurrentVC {
    GLCatagoryWeakWrapper *wrapper = objc_getAssociatedObject(self, @selector(getWeakCurrentVC));
    return wrapper.weakObj;
}

tips: 因为ObjC的selector的地址是固定的,所以可以用来作为associatedObject的key.

相关文章

网友评论

      本文标题:iOS类别Catagory添加weak属性

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