1. 概念
- OC-runtime( 运行时机制 ) 任何方法的调用, 本质都是发送消息
- 例如:
[person eat]
, 等同于[person performSelector:@Selector(eat)];
- 使用runtime, 要导入框架
#import <objc/message.h>
- 使用runtime, 发送消息. -> 谁(哪个方法)做事,就调用谁(那个方法)
- 类方法,本质 -> 把类名转换成类对象,->证据: 如果类不初始化, 是不能调用类方法的. 初始化就是实例化的类对象
- Xcode5以后, 苹果不建议使用底层方法, 比如runtime -> 表现: xcode导入
<objc/message.h>
. 是不给智能提示的
2. 使用场景
- 利用runtime, 交换系统方法和自定义方法的实现, 常用于单元测试时使用
导入 <objc/message.h>
获取类方法 class_getClassMethod(__unsafe_unretained Class cls, SEL name);
获取对象方法 class_getInstanceMethod(__unsafe_unretained Class cls, SEL name);
用方法类对象, 调用 method_exchangeeImplementations( Method m1, Method, m2 )
例如: Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
利用runtime, 给类动态添加方法, - - - 没理解具体的用法. 也许是在某个类的方法过多时,懒加载方法. 具体用到时再更新吧
- 使用场景: 如果一个类方法非常多, 加载类到内存的时候也比较耗费资源, 需要给每个方法生成映射表. 可以使用动态给某个类, 添加方法解决
1. 动态添加方法, 首先需要实现 +(BOOL) resolveInstanceMethod:(SEL)sel ,当调用了一个方法, 但方法没实现, 就会调用这个方法 2. 先知道SEL这个方法是否实现., 然后在上述方法里添加动态的方法 3. 导入<obj/message.h> 4. 然后可以动态添加方法 class_addMethod(__unsage_unreatined Class cls, SEL name, IMP imp, const char *types); 1. cls 给哪个类添加方法 2. SEL 添加方法的方法编号是什么 3. IMP 方法实现, 函数入口, 函数名 4. types 方法类型 5. class_addMethod(self, @selector(eat), (IMP)testMethod, “v@:”) 6. 每个方法, 必须有2个隐式参数 (id self, @SEL _cmd) , 7. 如果方法有参数 写法是 (id self, @SEL _cmd , id param_1) 8. class_addMethod(self, @selector(eat), (IMP)testMethod, “v@:@”)
- 使用场景: 如果一个类方法非常多, 加载类到内存的时候也比较耗费资源, 需要给每个方法生成映射表. 可以使用动态给某个类, 添加方法解决
利用runtime, 给类动态添加属性. - - - 不清楚具体的使用场景
1. 添加属性, 本质就是添加一种关联. 并不是在对象内部添加, 而是让对象与外部的一个属性产生关联 2. objc_setAssociatedObject(id object, const void *key, id value, objc_AssocationPolicy policy) 1. object 给哪个对象添加属性 2. key 属性名 根据key区获取关联对象 - - 在c语言里 void * 相当于 id 3. value 关联的值 4. policy 策略 - objc_Assocation_RETAIN_NONATOMIC 是一个枚举. assign copy retain
- 利用runtime, 字典转模型
- 思路: 利用runtime 遍历模型中所有属性, 根据模型的属性名, 去字典中查找key, 取出对应的值, 给模型的属性赋值
3. 相关博客
http://blog.csdn.net/wqt925497045/article/month/2016/04
http://blog.leichunfeng.com/blog/2015/05/18/objective-c-category-implementation-principle/