用RunTime给Category添加weak属性
2019-05-11 本文已影响0人
_moses
我们知道用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