iOS通过runtime给分类添加属性
时间:2022-06-19
本文章向大家介绍iOS通过runtime给分类添加属性,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
分类Category可以添加方法,但不能直接添加属性,如下,我们创建一个UIImage的Category:
WX20190327-130805@2x.png
WX20190327-130820@2x.png
咱们直接输入一个Url,最终得到的是:
image.png
这样一个分类,我们给其添加一个属性:
@property (nonatomic, copy) NSString *imageUrl;
这是编译一下,会报如下警告
image.png
而且如果这时在外部使用这个属性,运行会crash,并会报如下错误
调用set方法时
2019-03-27 13:18:03.497364+0800 Target[98782:2455630] ***
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UIImage setImageUrl:]:
unrecognized selector sent to instance 0x600002bc8ee0'
调用get方法时
2019-03-27 13:19:49.208647+0800 Target[98819:2456879] ***
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UIImage imageUrl]:
unrecognized selector sent to instance 0x600002950230'
原因就是这个分类属性找不到set和get方法,若要能正常使用这个属性的set和get方法,我们可以通过runtime来做到:
首先我们在.m里
#import <objc/runtime.h>
然后重写set和get方法
-(void)setImageUrl:(NSString *)imageUrl{
}
-(NSString *)imageUrl{
}
这时需要了解的函数是
//set
objc_setAssociatedObject(<#id _Nonnull object#>, <#const void * _Nonnull key#>, <#id _Nullable value#>, <#objc_AssociationPolicy policy#>)
//get
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
set有四个参数,get的参数可以参考set 1.源对象(self) 2.关联时的用来标记的key(因为可能会添加很多属性,我们这里是imageUrl,所以也需要一个imageUrl的key:& imageUrl_key)
//我们需要在.m里声明这个key
static NSString *imageUrl_key = @"imageUrl_key";
3.关联的对象(imageUrl) 4.一个关联策略(OBJC_ASSOCIATION_COPY)。
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并且关联对象使用原子性
};
最终的set和get方法是这样的
-(void)setImageUrl:(NSString *)imageUrl{
objc_setAssociatedObject(self, &imageUrl_key, imageUrl, OBJC_ASSOCIATION_COPY);
}
-(NSString *)imageUrl{
return objc_getAssociatedObject(self, &imageUrl_key);
}
这时在外部就能正常使用这个属性:
UIImage *image = [[UIImage alloc]init];
image.imageUrl = @"www.999999.com";
NSString *url = image.imageUrl;
- Vijos P1784 数字统计【模拟】
- 网络安全黑暗森林法则:2015 ISC 深度回顾
- Codeforces 626G Raffles(贪心+线段树)
- window.opener.location 安全风险讨论
- Vijos P1497 立体图【模拟】
- Vijos P1127 级数求和【模拟】
- 新型漏洞:利用浏览器Cookie绕过HTTPS并窃取私人信息
- Vijos P1113 不高兴的津津【模拟】
- Linux下MySQL的彻底卸载和安装配置字符集
- Codeforces 626F Group Projects(滚动数组+差分dp)
- Vijos P1103 校门外的树【线段树,模拟】
- BZOJ 1061: [Noi2008]志愿者招募【单纯形裸题】
- SQL vs NoSQL:如何选择?
- 线性规划之单纯形法【超详解+图解】
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 大点干!早点散----------LVS负载均衡之LVS-NAT部署实战
- 大点干!早点散----------负载均衡LVS-DR群集部署
- 大点干!早点散----------群集负载均衡LVS DR+keepalived部署实战
- Java字符串所占字节数的小总结
- Java类加载机制详解
- 详解Java注解(Annotation)
- 你不知道的Synchronized
- 从Java并发集合看锁优化策略
- Java常用并发容器总结(二)
- Java常用并发容器总结(一)
- Java常用并发容器总结(三)
- Java常用并发容器总结(四)
- Js常见点击跳转方式
- Js获取域名地址并截取
- 引用lib-flexible导致第三方Ui库缩小