Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西。
什么是 Runtime
1.我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如 [target doSomething] 会被转化成 objc_msgSend(target, @selector(doSomething));。
2.OC中一切都被设计成了对象,我们都知道一个类被初始化成一个实例,这个实例是一个对象。实际上一个类本质上也是一个对象,在runtime中用结构体表示。
3.相关定义
/// 描述类中的一个方法
typedef struct objc_method *Method;
/// 实例变量
typedef struct objc_ivar *Ivar;
/// 类别Category
typedef struct objc_category *Category;
/// 类中声明的属性
typedef struct objc_property *objc_property_t;
4.类在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 *` */
获取列表
有时候会有这样的需求,我们需要知道当前类中每个属性的名字(比如字典转模型,字典的Key和模型对象的属性名字不匹配)。
我们可以通过runtime的一系列方法获取类的一些信息(包括属性列表,方法列表,成员变量列表,和遵循的协议列表)。
unsigned int count;
//获取属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &count); for (unsigned int i=0; i%@", [NSString stringWithUTF8String:propertyName]); } //获取方法列表
Method *methodList = class_copyMethodList([self class], &count);
for (unsigned int i; i%@", NSStringFromSelector(method_getName(method))); } //获取成员变量列表
Ivar *ivarList = class_copyIvarList([self class], &count); for (unsigned int i; i%@", [NSString stringWithUTF8String:ivarName]); }
//获取协议列表
__unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);
for (unsigned int i; i%@", [NSString stringWithUTF8String:protocolName]);
}
在Xcode上跑一下看看输出吧,需要给你当前的类写几个属性,成员变量,方法和协议,不然获取的列表是没有东西的。注意,调用这些获取列表的方法别忘记导入头文件#import<objc/runtime.h>。