iOS 用runtime为分类添加成员变量或属性

关于iOS分类:很多说法是只能添加方法,而不能添加成员变量或属性。有些人可能知道,这种说法是不严谨的,并不是绝对不能添加变量。 解释如下: 我们知道在一个类中用@property声明属性,编译器会自动帮我们生成_成员变量和setter/getter,但分类的指针结构体中,根本没有属性列表。所以在分类中用@property声明属性,既无法生成_成员变量也无法生成setter/getter。 因此结论是:我们可以用@property声明属性,编译会通过,但run之后就会崩溃。

那么问题来了。。 既然报错的根本原因是使用了系统没有生成的setter/getter方法,可不可以在手动添加setter/getter来避免崩溃,完成调用呢?其实是可以的。由于OC是动态语言,方法真正的实现是通过runtime完成的,虽然系统不给我们生成setter/getter,但我们可以通过runtime手动添加setter/getter方法。那具体怎么实现呢?

举例如下: 分类.h

@interface CustomView (dd)

- (NSString *)name;
- (void)setName:(NSString *)name;

@end
复制代码

分类.m

@implementation CustomView (dd)

/*
 * 使用关联对象模拟实例变量
 * 使用objc_getAssociatedObject、objc_setAssociatedObject模拟『属性』的存取方法
 */

- (NSString *)name{
    
    return objc_getAssociatedObject(self, _cmd);
    
}

- (void)setName:(NSString *)name{
    
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
}
@end
复制代码

重点就是两个runtime实现方法,如果不写这个,只要你申明了属性,运行肯定会报错;如果加了这两个方法,就能正常使用。 关联策略的解释如下:

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy){

    OBJC_ASSOCIATION_ASSIGN = 0, //关联对象的属性是弱引用 

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //关联对象的属性是强引用并且关联对象不使用原子性

    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //关联对象的属性是copy并且关联对象不使用原子性

    OBJC_ASSOCIATION_RETAIN = 01401, //关联对象的属性是copy并且关联对象使用原子性

    OBJC_ASSOCIATION_COPY = 01403 //关联对象的属性是copy并且关联对象使用原子性
};
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值