mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 04:17:17 +00:00
feat: refine
This commit is contained in:
@@ -141,7 +141,7 @@ isa 在 arm64 之后必须通过 `ISA_MASK` 去查询 class(类对象、元类
|
||||
|
||||
`0x0000000ffffffff8ULL` 用程序员模式打开计算器
|
||||
|
||||

|
||||

|
||||
|
||||
其中,结构体中的数据存放大体是下面的结构:
|
||||
|
||||
@@ -343,7 +343,7 @@ struct class_ro_t {
|
||||
|
||||
具体关系整理如下图
|
||||
|
||||

|
||||

|
||||
|
||||
说明:
|
||||
|
||||
@@ -351,7 +351,7 @@ struct class_ro_t {
|
||||
|
||||
为什么不是二维数组?因为Array 中的子 Array长度不一致,且不能补空
|
||||
|
||||

|
||||

|
||||
|
||||
```c
|
||||
static void remethodizeClass(Class cls)
|
||||
@@ -436,7 +436,7 @@ struct class_ro_t {
|
||||
|
||||
- `class_ro_t` 里面的 baseMethodList、baseProtocols、ivars、baseProperties 是一维数组,是只读的,包含了类的(原始信息)初始内容
|
||||
|
||||

|
||||

|
||||
|
||||
## Method_t
|
||||
|
||||
@@ -474,7 +474,7 @@ typedef struct objc_selector *SEL;
|
||||
|
||||
iOS 中提供了一个叫做 `@encode` 的指令,可以将具体的类型表示成字符串编码
|
||||
|
||||

|
||||

|
||||
|
||||
```objectivec
|
||||
- (int)calcuate:(int)age heigith:(float)height;
|
||||
@@ -826,7 +826,7 @@ NSLog(@"%s %p", bucket._key, bucket._imp);
|
||||
// personSay 0xbec8
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
原理就是根据类对象结构体找到 cache 结构体,cache 结构体内部的 `_buckets` 是一个方法散列表,查看源代码,根据散列表的哈希寻找策略 `(key & mask)` 找到哈希索引,然后找到方法对象 bucket,其中寻找方法索引的 key 就是 方法 selector。
|
||||
|
||||
@@ -1411,7 +1411,7 @@ for 循环不断查找,找当前类的父类,直到当前类为 nil。
|
||||
|
||||
上面的流程是整个 `objc_msgSend` 的消息发送阶段的整个流程。可以用下图表示
|
||||
|
||||

|
||||

|
||||
|
||||
### 动态方法解析阶段
|
||||
|
||||
@@ -1546,7 +1546,7 @@ SEL_resolveClassMethod, sel);`
|
||||
|
||||
完整流程如下
|
||||
|
||||

|
||||

|
||||
|
||||
上 Demo
|
||||
|
||||
@@ -1686,7 +1686,7 @@ void *_objc_forward_handler = (void*)objc_defaultForwardHandler;
|
||||
|
||||
为什么是 `__forwarding__` 方法。我们可以根据 Xcode 崩溃窥探一二
|
||||
|
||||

|
||||

|
||||
|
||||
```c
|
||||
int __forwarding__(void *frameStackPointer, int isStret) {
|
||||
@@ -1730,7 +1730,7 @@ int __forwarding__(void *frameStackPointer, int isStret) {
|
||||
|
||||
完整流程如下
|
||||
|
||||

|
||||

|
||||
|
||||
上 Demo
|
||||
|
||||
@@ -1951,7 +1951,7 @@ objc_msgSendSuper(arg, sel_registerName("class"))
|
||||
|
||||
我们对 iOS 项目`[super viewDidLoad]` 下符号断点,发现`objc_msgSendSuper2`
|
||||
|
||||

|
||||

|
||||
|
||||
查看 objc4 源代码发现是一段汇编实现。
|
||||
|
||||
@@ -2185,7 +2185,7 @@ void test () {
|
||||
|
||||
方法内的变量存储在栈上,堆向上增长,栈向下增长。
|
||||
|
||||

|
||||

|
||||
|
||||
3.**实例对象的本质就是一个结构体,存储所有成员变量(isa 是一个特殊成员变量,其他的成员变量,这里就是 _name),`sayHi` 方法内部的 self 就是 obj,找成员变量的本质就是找内存地址的过程(此时就是偏移8个字节)**
|
||||
|
||||
@@ -2234,7 +2234,7 @@ objc_msgSendSuper(arg, sel_registerName("viewDidLoad"));
|
||||
|
||||
所以此时的“前一个局部变量” 也就是结构体 `objc_super` 类型的 arg。arg 是一个结构体,结构体第一个成员变量就是 self,所以“前一个局部变量” 也就是 self(ViewController)
|
||||
|
||||

|
||||

|
||||
|
||||
## 应用场景
|
||||
|
||||
@@ -2268,7 +2268,7 @@ Person *p = [Person new];
|
||||
object_setClass(p, [Student class]);
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
3.动态创建类
|
||||
|
||||
@@ -2295,7 +2295,7 @@ void createClass (void) {
|
||||
}
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
runtime 中 copy、create 等出来的内存,不使用的时候需要手动释放`objc_disposeClassPair(newClass>)`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user