深入浅出Runtime
2018-11-21 本文已影响0人
我叫王可可
Runtime运行时
目录
一、runtime 简介
二、消息机制<了解>
2.1 消息机制原理
2.2 消息调用流程
三、常用开发场景
3.1 UITextField 占位文字的颜色以及字体大小
3.2 给分类动态添加属性
四、面试须知
4.1 动态添加方法(开发中几乎不用但面试须知)
4.2 使用 runtime 实现自动归档和接档
4.3 Method Swizzling 方法交换(俗称黑魔法,也有方法叫方法欺骗)
4.4 runtime 字典转模型(解析都是使用第三方框架,MJExtension 字典转模型也是对 runtime 的封装,才可以把一个模型中的所有属性遍历出来。)
五、利用 runtime 进行实用性封装
5.1 UIAlertView 的封装
5.2 Method Swizzling 方法交换封装
5.3 自动归档和解档定义成宏
一、Runtime 简介
- runtime 简称运行时,OC 就是运行机制,也就是运行时候的一些机制,其中最主要的是消息机制。
- 对于 C 语言,函数的调用是在编译的时候会决定调用那个函数
- 对于 OC 的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数名称找到对应的函数来调用。
二、消息机制
2.1 消息机制原理
方法调用本质:让对象发送消息
- objc_msgSend只有对象才能发送消息,所以用objc开头
- 使用消息机制必须导入#import
- runtime 都有一个前缀,谁的事情使用谁
解决提示的步骤
- 查找 build setting -> 搜索 msg -> 设为 NO
查看生成的 runtime 代码,首先终端切换到该目录回车后输入 clang -rewrite-objc main.m
2.2 消息调用流程
1.通过 *isa* 去对应的类中查找
2.注册方法编号
3.根据方法编号去查找对应方法
4.找到只是最终函数实现地址,根据地址去方法区调用对应函数
1516585677787801.png
三、常用开发场景
3.1 UITextField 占位文字的颜色以及字体大小
[textField setValue:[NSFont systemOfSize:14] forKeyPath:@"_placeholderLabel.font"];
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
3.2 给分类动态添加属性
注意:在分类中是不能够添加成员属性,虽然使用了 @property ,但是仅仅会自动生成 get 和 set 方法的声明,并没有带下划线的属性和方法实现生成。但是我们可以通过 runtime 就可以做到给它的方法实现。
原理:给一个类声明属性,其本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间。
#import "NSObject+Person.h"
#import static char const * const kName = "kName";
@implementation NSObject (Person)
- (void)setName:(NSString *)name{
/*
objc_setAssociatedObject(将某个值跟某个对象关联起来,将某个值存储到某个对象中)
: 给哪个对象添加属性
:属性名称
:属性值
:保存策略
**/
objc_setAssociatedObject(self, kName, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)name{
//objc_getAssociatedObject:获取某个对象的值
return objc_getAssociatedObject(self, kName);
}
/*************调用******************/
NSObject *obj =[NSObject new];
obj.name = @"flowerflower";
NSLog(@"我是分类obj中的%@",obj.name);
/*************打印输出******************/
我是分类obj中的flowerflower
小结:
属性赋值的本质就是让属性与一个对象产生关联,而 runtime 可以做到这一点。
四、面试须知
4.1 动态添加方法
4.2 实现自动归档和接档
4.3 方法交换(俗称黑魔法,也叫方法欺骗)
五、利用 runtime 进行实用性封装
5.1 UIAlertView 的封装
5.2 自动归档和解档定义成宏