新增类及其成员
1.API
To create a new class, start by calling objc_allocateClassPair. Then set the class’s attributes with functions like class_addMethod and class_addIvar. When you are done building the class, call objc_registerClassPair. The new class is now ready for use.
Instance methods and instance variables should be added to the class itself. Class methods should be added to the metaclass.
1.1.增加类
1 |
|
这两个方法配对使用,在二者之间增加成员变量、属性、实例方法和类方法等。调用第二个方法即注册类,这之后类的结构也就固定下来,不能再向类中增加新的成员变量,但是可以增加属性和方法。其中新增的属性不会自动生成_属性名
成员变量,也不会提供setter与getter函数及其实现。
1.2.增加方法
1 |
|
- 实例方法应该加到当前实例的isa指向的类中;
- 类方法则应该加到当前类的元类中;
1.3.增加成员变量
1 |
|
This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.
The class must not be a metaclass. Adding an instance variable to a metaclass is not supported.
新增成员变量应该在类注册完成之前进行,类注册完成之后类结构已固定,实例的内存空间已经确定,不能再增加新的成员变量。
新增加的成员变量应该加到实例对象所属的类中,而不能加到其所属类的元类中。
1.4.增加属性
1 |
|
2.示例
1 |
|
其中RuntimeTool
是工具类,用来获取成员变量、属性和方法列表,实现代码如下:
1 |
|
注意:直接调用objc_msgSend
在编译时会报错,需要在 “Build Setting”中,把“ Enable Strict Checking of objc_msgSend Calls” 关掉。
示例运行后输出日志:
1 |
|
从日志中也可以得出结论:
1、在类allocate
与register
之间可以添加成员变量
、属性
和方法
;
2、在register
之后,即类结构固定之后不能
再添加成员变量
,但可以继续添加属性
和方法
;
3、动态添加的属性,不会创建对应的以_
开头的成员变量,这一步需要由编译器来完成。
ps: 热更新JSPatch
就是在OC的 runtime 基础上实现的,大致原理是:JS传递字符串给OC,OC通过 Runtime 的运行时函数,调用和替换相应的OC方法。待后期慢慢研究。。