在iOS开发工程中,我们每天都会使用到ObjC,也会用到runtime的很多操作msgSend,method_swizzling,objc_setAssociatedObject,objc_getAssociatedObject等常用的runtime操作,那runtime究竟是怎样实现的呢?我们底层的数据结构又是怎样的呢?带着这些问题,开始学习runtime相关的内容。
源码地址: objc4源代码
我们看到我们最常引入的头文件#import<objc/runtime.h>,我们可以看到runtime定义了ObjC的运行时状态,类、属性、方法、协议、拓展等内容的实现。下面我们从类的定义开始阅读。
objc_class
类的定义,定义具体代码如下
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
从上面的代码可以看出来类的定义是以结构的形式实现,包含有类本身及父类的信息,属性列表、方法列表、缓存和协议列表。
objc_ivar
objc_ivar_list定义了属性类的属性列表,在objc_ivar_list包含了一个objc_ivar的一个数组,通过这两个结构实现类的属性存储。
struct objc_ivar {
char * _Nullable ivar_name OBJC2_UNAVAILABLE;
char * _Nullable ivar_type OBJC2_UNAVAILABLE;
int ivar_offset OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
struct objc_ivar_list {
int ivar_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
objc_method
和属性一样objc_method_list中同样包含了一个objc_method的数组,通过这两个方法实现了方法列表。
struct objc_method {
SEL _Nonnull method_name OBJC2_UNAVAILABLE;
char * _Nullable method_types OBJC2_UNAVAILABLE;
IMP _Nonnull method_imp OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
struct objc_method_list {
struct objc_method_list * _Nullable obsolete OBJC2_UNAVAILABLE;
int method_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
Protocol
protocol的实现方式和method和ivar类似,他们都有一个objc_protocol_list以及Protocol的数组去实现协议的列表,不同的是Protocol的实现不再是一个结构,而是一个继承自NSObject的类。
struct objc_protocol_list {
struct objc_protocol_list * _Nullable next;
long count;
__unsafe_unretained Protocol * _Nullable list[1];
};
objc_category
category 定义了Category的数据结构,通过category_name区分不同的category,通过class_name关联相关的类。
struct objc_category {
char * _Nonnull category_name OBJC2_UNAVAILABLE;
char * _Nonnull class_name OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable instance_methods OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable class_methods OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
如上就是runtime相关的定义。然后一些常用的操作又是怎么实现的呢?我们在进一步的学习其他的相关操作。
更好的阅读体验可以参考个人网站:https://zevwings.com