最近了解了一下OC的Runtime,真的是OC中很强大的一个机制,看起来比较底层,但其实可以有很多活用的方式。
什么是Runtime
我们虽然是用Objective-C写的代码,其实在运行过程中都会被转化成C代码去执行。比如说OC的方法调用都会转成C函数 id objc_msgSend ( id self, SEL op, … ); 而OC中的对象其实在Runtime中都会用结构体来表示,这个结构体中包含了类名、成员变量列表、方法列表、协议列表、缓存等。
类在Runtime中的表示:
struct objc_class {
Class isa;//指针,顾名思义,表示是一个什么,
//实例的isa指向类对象,类对象的isa指向元类
#if !__OBJC2__
Class super_class; //指向父类
const char *name; //类名
long version;
long info;
long instance_size
struct objc_ivar_list *ivars //成员变量列表
struct objc_method_list **methodLists; //方法列表
struct objc_cache *cache;//缓存
//一种优化,调用过的方法存入缓存列表,下次调用先找缓存
struct objc_protocol_list *protocols //协议列表
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
整个Runtime机制其实可以挖的点很多,这里只是简单的介绍一些常见的用法,如果将其细细解析,相信一定会对OC的理解加深几个层面。
获取属性/方法/协议列表
最直接的一种用法,就是获取我们的结构体中存储的对象的属性、方法、协议等列表,从而获取其所有这些信息。
要获取也比较简单,但是自己尝试之前需要注意几点:
- 一定要自己给类加几个属性、方法,遵循一些协议,否则当然是看不到输出信息的。
- 要使用这些获取的方法,需要导入头文件 #import
#import <objc/runtime.h>
// 输出类的一些信息
- (void)logInfo {
unsigned int count;// 用于记录列表内的数量,进行循环输出
// 获取属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for (unsigned int i =