博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 用runtime为分类添加成员变量或属性
阅读量:6452 次
发布时间:2019-06-23

本文共 1296 字,大约阅读时间需要 4 分钟。

关于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并且关联对象使用原子性};复制代码

转载地址:http://magwo.baihongyu.com/

你可能感兴趣的文章
Centos 6.3编译安装nagios
查看>>
如何实现7*24小时灵活发布?阿里技术团队这么做
查看>>
iSCSI
查看>>
java1234_Activiti_第6讲_一般程序员使用的函数
查看>>
mysql拷贝表的几种方式
查看>>
NetApp FAS2240-4存储删除文件数据恢复
查看>>
用设计模式去掉没必要的状态变量 —— 状态模式
查看>>
linux安装elasticsearch及遇到的各种问题
查看>>
健忘的正则
查看>>
[转]CMake快速入门教程:实战
查看>>
IntelliJ IDEA创建JavaWeb工程及配置Tomcat部署
查看>>
Markdown用法
查看>>
求最大值及其下标
查看>>
Request header is too large
查看>>
轮播插件swiper.js?
查看>>
网路流24题总结
查看>>
BZOJ-3732 Network 图论 最小生成树 倍增
查看>>
python之文件操作
查看>>
15 个 Android 通用流行框架大全
查看>>
Entity Framwork CodeFirst 学习笔记五:数据库映射的默认配置和设置
查看>>