feat: refine

This commit is contained in:
LiuBinPeng
2022-05-30 15:03:36 +08:00
parent 6cd0cf5144
commit 55d66cc4c5
15 changed files with 149 additions and 149 deletions

View File

@@ -141,7 +141,7 @@ isa 在 arm64 之后必须通过 `ISA_MASK` 去查询 class类对象、元类
`0x0000000ffffffff8ULL` 用程序员模式打开计算器
![](./../assets/objc-isa-mask.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/objc-isa-mask.png)
其中,结构体中的数据存放大体是下面的结构:
@@ -343,7 +343,7 @@ struct class_ro_t {
具体关系整理如下图
![](./../assets/runtime-class.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-class.png)
说明:
@@ -351,7 +351,7 @@ struct class_ro_t {
为什么不是二维数组因为Array 中的子 Array长度不一致且不能补空
![](./../assets/runtime-class-rw-t.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-class-rw-t.png)
```c
static void remethodizeClass(Class cls)
@@ -436,7 +436,7 @@ struct class_ro_t {
- `class_ro_t` 里面的 baseMethodList、baseProtocols、ivars、baseProperties 是一维数组,是只读的,包含了类的(原始信息)初始内容
![](./../assets/runtime-class-ro-t.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-class-ro-t.png)
## Method_t
@@ -474,7 +474,7 @@ typedef struct objc_selector *SEL;
iOS 中提供了一个叫做 `@encode` 的指令,可以将具体的类型表示成字符串编码
![](./../assets/runtime-method-encoding.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-method-encoding.png)
```objectivec
- (int)calcuate:(int)age heigith:(float)height;
@@ -826,7 +826,7 @@ NSLog(@"%s %p", bucket._key, bucket._imp);
// personSay 0xbec8
```
![](./../assets/runtime-method-find.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-method-find.png)
原理就是根据类对象结构体找到 cache 结构体cache 结构体内部的 `_buckets` 是一个方法散列表,查看源代码,根据散列表的哈希寻找策略 `(key & mask)` 找到哈希索引,然后找到方法对象 bucket其中寻找方法索引的 key 就是 方法 selector。
@@ -1411,7 +1411,7 @@ for 循环不断查找,找当前类的父类,直到当前类为 nil。
上面的流程是整个 `objc_msgSend` 的消息发送阶段的整个流程。可以用下图表示
![](./../assets/runtime-objc_msgSend-messageSend.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-objc_msgSend-messageSend.png)
### 动态方法解析阶段
@@ -1546,7 +1546,7 @@ SEL_resolveClassMethod, sel);`
完整流程如下
![](./../assets/runtime-objc_msgSend-ResolveMethod.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-objc_msgSend-ResolveMethod.png)
上 Demo
@@ -1686,7 +1686,7 @@ void *_objc_forward_handler = (void*)objc_defaultForwardHandler;
为什么是 `__forwarding__` 方法。我们可以根据 Xcode 崩溃窥探一二
![](./../assets/runtime-forwardingFailed.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-forwardingFailed.png)
```c
int __forwarding__(void *frameStackPointer, int isStret) {
@@ -1730,7 +1730,7 @@ int __forwarding__(void *frameStackPointer, int isStret) {
完整流程如下
![](./../assets/runtime-forwarding.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-forwarding.png)
上 Demo
@@ -1951,7 +1951,7 @@ objc_msgSendSuper(arg, sel_registerName("class"))
我们对 iOS 项目`[super viewDidLoad]` 下符号断点,发现`objc_msgSendSuper2`
![](./../assets/runtime-super.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-super.png)
查看 objc4 源代码发现是一段汇编实现。
@@ -2185,7 +2185,7 @@ void test () {
方法内的变量存储在栈上,堆向上增长,栈向下增长。
![](./../assets/runtime-isa-demo.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-isa-demo.png)
3.**实例对象的本质就是一个结构体存储所有成员变量isa 是一个特殊成员变量,其他的成员变量,这里就是 _name`sayHi` 方法内部的 self 就是 obj找成员变量的本质就是找内存地址的过程此时就是偏移8个字节**
@@ -2234,7 +2234,7 @@ objc_msgSendSuper(arg, sel_registerName("viewDidLoad"));
所以此时的“前一个局部变量” 也就是结构体 `objc_super` 类型的 arg。arg 是一个结构体,结构体第一个成员变量就是 self所以“前一个局部变量” 也就是 selfViewController
![](./../assets/runtime-super-isa-demo.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-super-isa-demo.png)
## 应用场景
@@ -2268,7 +2268,7 @@ Person *p = [Person new];
object_setClass(p, [Student class]);
```
![](./../assets/runtime-changeisa-demo.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-changeisa-demo.png)
3.动态创建类
@@ -2295,7 +2295,7 @@ void createClass (void) {
}
```
![](./../assets/runtime-dynamicCreateClass-demo.png)
![](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/runtime-dynamicCreateClass-demo.png)
runtime 中 copy、create 等出来的内存,不使用的时候需要手动释放`objc_disposeClassPair(newClass>)`