在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