类的 class_rw_t 结构体的 flags 信息
#define RW_REALIZED (1<<31)// class_t->data 的结构为 class_rw_t,非class_ro_t
#define RW_METHODIZED (1<<30)// 类的方法列表已修复
#define RW_INITIALIZED (1<<29)// 类已经初始化了
#define RW_INITIALIZING (1<<28)// 类在初始化过程中
#define RW_COPIED_RO (1<<27)// class_rw_t->ro 是 class_ro_t 的堆副本
#define RW_CONSTRUCTING (1<<26)// 类分配了内存,但没有注册
#define RW_CONSTRUCTED (1<<25)// 类分配了内存也注册了
#define RW_FINALIZE_ON_MAIN_THREAD (1<<24)// GC:class有不安全的finalize方法
#define RW_LOADED (1<<23)// 类的 +load 被调用了
#define RW_REALIZING (1<<19)// 类已开始分配,但并未完成
一、动态添加类
//初始化
objc_allocateClassPair(_:_:_:)->objc_initializeClassPair_internal(_:_:_:_:)
//设置flags标记信息
//类分配了内存,但没有注册|class_rw_t->ro 是 class_ro_t
| class_t->data 的结构为 class_rw_t | 类已开始分配,但并未完成
cls->data()->flags = RW_CONSTRUCTING | RW_COPIED_RO | RW_REALIZED | RW_REALIZING;
meta->data()->flags = RW_CONSTRUCTING | RW_COPIED_RO | RW_REALIZED | RW_REALIZING;
//注册到内存
objc_registerClassPair(_:)
cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
二、添加成员变量
This function may only be called after objc_allocateClassPair(_:_:_:) and before objc_registerClassPair(_:). Adding an instance variable to an existing class is not supported.
这个功能只能在 objc_allocateClassPair(_:_:_:) 之后和 objc_registerClassPair(_:) 之前调用。不支持将实例变量添加到现有的类。
The class must not be a metaclass. Adding an instance variable to a metaclass is not supported.
该类不能是元类。不支持将实例变量添加到元类。
class_addIvar()
// Can only add ivars to in-construction classes.
if (!(cls->data()->flags & RW_CONSTRUCTING)) {
return NO;
}
三、添加成员变量addIvar
Class Person = objc_allocateClassPair([NSObject class], "Person", 0);
objc_registerClassPair(Person);
class_addIvar(Person, "name", sizeof(NSString *), 0, "@");
无法添加成功
1、类注册到内存中后,ro无法修改。
2、在类注册到内存后,底层源码把类的flags值修改了,再调用class_addIvar()时,判断flags直接returnNO了。
四、添加属性
class_addProperty(_:_:_:_:);//Person添加name属性
[Person setValue:@"nn" forKey:@"name"];
调用会闪退
因为setValue: forKey:的本质是调用setName方法,直接调用会无法找到方法,必须先动态添加set、get方法