docs: image url

This commit is contained in:
FantasticLBP
2026-01-02 10:28:57 +08:00
parent 7ac7513900
commit 7843661458
29 changed files with 719 additions and 719 deletions

View File

@@ -24,7 +24,7 @@
在需要触发 KVO 的地方,先调用 `willChangeValueForKey`,然后更改被观察对象的属性值,最后调用 `didChangeValueForKey` 方法。
<img src="./../assets/KVOInvokeWhenChangeIvarDirectlyMustCallWillChangeAndDidChange.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOInvokeWhenChangeIvarDirectlyMustCallWillChangeAndDidChange.png" style="zoom:25%">
@@ -214,7 +214,7 @@ Demo: 实时数据流处理
代码如下
<img src="./../assets/KVOObservePropertyIsObject.png" style="zoom:40%" />
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOObservePropertyIsObject.png" style="zoom:40%" />
看上去很麻烦,有没有优雅点的方案?
@@ -224,7 +224,7 @@ Demo: 实时数据流处理
实现如下:
<img src="./../assets/KVOObservePropertyIsObjectUseAPI.png" style="zoom:40%" />
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOObservePropertyIsObjectUseAPI.png" style="zoom:40%" />
注意:在对 Person 对象的 `dog` 属性进行监听后Person 内部需要实现 `+`keyPathsForValuesAffectingValueForKey 方法,判断 key 为 `@"dog"` 后,想监听 dog 的哪个属性变化就通知 Person 对象的观察者收到响应的话就写上去。但注意绿色框里面set 添加的内容,必须换个名字,比如 `@"_dog.name"`,不能是 `@"dog.name"`。这会导致循环依赖或逻辑矛盾
@@ -326,7 +326,7 @@ self.p1.dog.name = @"Lucy";
可以在下面的 Demo1 中可以看到 KVO 无法直接对数组进行 KVO 监听。但系统为了方便,也提供了容器类的接口,比如针对 `NSMutableArray` 系统就提供了 `mutableArrayValueForKey` 接口。
<img src="./../assets/KVOObserveNSMutableArrayUseAPI.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOObserveNSMutableArrayUseAPI.png" style="zoom:25%">
那么虽然功能实现了,我们可以想想,这个接口背后做了哪些事?
@@ -434,7 +434,7 @@ FBKVO 工作原理:
### Demo1
<img src="./../assets/KVOInstanceVariableCannotObserve.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOInstanceVariableCannotObserve.png" style="zoom:25%">
可以发现对成员变量添加观察者的时候成员变量的值变化了KVO 也是监听不到的
@@ -442,13 +442,13 @@ FBKVO 工作原理:
### Demo2
<img src="./../assets/KVOCannotObserveNSMutableArray.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOCannotObserveNSMutableArray.png" style="zoom:25%">
可以看到对 NSMutableArray 类型的属性添加了 KVO。然后点击屏幕NSMutableArray 里添加了元素,但是观察方法没有触发。
对实验进行改进下
<img src="./../assets/KVOObserveNSMutableArray.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOObserveNSMutableArray.png" style="zoom:25%">
结论: **KVO 只可以对属性的 setter 方法起作用**。
@@ -458,7 +458,7 @@ FBKVO 工作原理:
创建 Person 类,点击事件里触发属性值的改变
<img src="./../assets/XCodoKVOIsaInspect.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XCodoKVOIsaInspect.png" style="zoom:25%">
分析:
@@ -468,7 +468,7 @@ FBKVO 工作原理:
在内存中的结构如下图
<img src="./../assets/UnusedKVOIsaStructure.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/UnusedKVOIsaStructure.png" style="zoom:25%">
整个流程分析下:
@@ -478,11 +478,11 @@ FBKVO 工作原理:
当我们按照 KVO 后动态生成的类名去创建一个新的类的时候Xcode 会报错:`[general] KVO failed to allocate class pair for name NSKVONotifying_Person, automatic key-value observing will not work for this class`。因为自己创建的类名和系统将要动态创建的类名冲突了,并且 KVO 监听失效
<img src="./../assets/SelfClassNameConflictsWithKVOClass.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/SelfClassNameConflictsWithKVOClass.png" style="zoom:25%">
### Demo4
<img src="./../assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
分析:
@@ -494,7 +494,7 @@ FBKVO 工作原理:
### Demo5
<img src="./../assets/KVOMethodImplAddressWithDouble.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOMethodImplAddressWithDouble.png" style="zoom:25%">
可以看到我们将 KVO 的数据类型改为 double 后,原本的 setHeight 是 `_NSSetLongLongValueAndNotify`,现在是 `_NSSetDoubleValueAndNotify`
@@ -504,11 +504,11 @@ FBKVO 工作原理:
### NSSet**ValueAndNotify 的内部实现
<img src="./../assets/UsedKVOIsaStructure.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/UsedKVOIsaStructure.png" style="zoom:25%">
来对 Person 类增加一些打印方法
<img src="./../assets/KVOKeyMethodPrint.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOKeyMethodPrint.png" style="zoom:25%">
@@ -577,7 +577,7 @@ FBKVO 工作原理:
### 重写 class 方法
<img src="./../assets/KVOOverrrideClassMethod.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOOverrrideClassMethod.png" style="zoom:25%">
可以看到利用 runtime api在添加 KVO 之后,类对象为 `NSKVONotifying_Person`
@@ -589,7 +589,7 @@ FBKVO 工作原理:
### KVO 类的所有方法
<img src="./../assets/PrintKVOClassAllMethodName.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/PrintKVOClassAllMethodName.png" style="zoom:25%">
@@ -663,7 +663,7 @@ Apple 文档告诉我们:被观察对象的 `isa指针` 会指向一个中间
- 键值观察通知依赖于 NSObject 的两个方法:`willChangeValueForKey:、didChangeValueForKey:` 。在一个被观察属性改变之前,调用 `willChangeValueForKey:` 记录旧的值。在属性值改变之后调用 `didChangeValueForKey:`,从而 `observeValueForKey:ofObject:change:context:` 也会被调用。
![KVO原理图](./../assets/2018_11_12_KVO.png)
![KVO原理图](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018_11_12_KVO.png)
@@ -809,7 +809,7 @@ KVO 的改装:
KVC 之后会触发 KVO 吗?
<img src="./../assets/KVCWillTriggerKVO.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVCWillTriggerKVO.png" style="zoom:25%">
发现 KVC 触发了 KVO。
@@ -817,7 +817,7 @@ KVC 之后会触发 KVO 吗?
整个流程如下
<img src="./../assets/KVC-process.png" style="zoom:45%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVC-process.png" style="zoom:45%">
`[self.person setValue:@10 forKey:@"age"]` 会先调用 `setKey:` 同名的方法,找不到则调用 `_setKey:` 的方法,如果还是找不到则调用 `+(BOOL)accessInstanceVariableDirectlt`,如果该方法返回 YES则可以直接修改成员变量的值会按照 `_key`、`_isKey`、`key`、`isKey` 的顺序寻找成员变量,如果找到则直接赋值,没找到则抛出异常 `NSUnknownKeyException`
@@ -874,7 +874,7 @@ KVC 之后会触发 KVO 吗?
<img src="./../assets/KVC-get-process.png" style="zoom:45%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVC-get-process.png" style="zoom:45%">