how to add weak property for iOS Category

给分类添加delegate属性

分类可以方便的对现有类进行扩展, 一般是新增方法, 但是有时候难以避免的, 我们可能需要为分类添加属性, 通常我们使用关联对象实现此功能.

然而,当我们希望添加weak类型的属性时, 会遇到一点点困难, 比如为分类添加delegate属性.

我们希望delegate对象存在时, 正常使用此属性对象,而当delegate对象释放时, 此delegate属性可以像真正的weak属性那样自动置为nil.然后关联对象本身并不能实现这一点.

如果我们使用assign类型的关联对象添加此属性, 还肯能导致程序发生crash.因为当delegate释放时, delegate所记录的值还存在, 此时访问他就会发生crash,因为访问了已经释放的对象地址.

那么我们应该如何解决这个问题呢?

嵌套weak属性

解决办法是:给分类添加strong属性的关联对象, 这个关联对象持有一个真正的weak属性, 然后把delegate对象赋值给这个weak属性.

嵌套了weak属性的container类:

@interface HWLAssociatedObjContainer : NSObject
@property (nonatomic, weak) id <NSObject> weakObj;
@end

@implementation HWLAssociatedObjContainer
@end

使用container实现weak属性的分类

@interface HWLCategoryClass (weakProperty)
@property (nonatomic, weak) id<someProtocol> obj_delegate;
@end

@interface HWLCategoryClass ()
@property (nonatomic, strong) HWLAssociatedObjContainer *obj_delegateContainer;
@end

@implementation HWLCategoryClass (weakProperty)


- (id< HWLAssociatedObjContainer >) obj_delegate {
    return (id<someProtocol>)self.nav_delegateContainer.weakObj;
}

- (void)setObj_delegate:(id<someProtocol>) obj_delegate {
    if (self.obj_delegateContainer) {
        self.obj_delegateContainer.weakObj = obj_delegate;
    } else {
        HWLAssociatedObjContainer *tAssociatedObjContainer = [[HWLAssociatedObjContainer alloc] init];
        tAssociatedObjContainer.weakObj = obj_delegate;
        self.obj_delegateContainer = tAssociatedObjContainer;
    }
}

- (HWLAssociatedObjContainer*)obj_delegateContainer {
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setObj_delegateContainer:(HWLAssociatedObjContainer *)obj_delegateContainer {
    objc_setAssociatedObject(self, @selector(obj_delegateContainer), obj_delegateContainer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

如上代码所示,

给分类添加strong关联对象属性,此strong关联对象持有一个weak属性,

当给delegate赋时, 检查strong关联对象是否存在, 不存在则创建.然后给此strong关联对象的weak属性赋值delegate对象.

这样当delegate对象释放时, strong关联对象持有的weak属性会自动置nil.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值