mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-25 04:17:17 +00:00
feature: App 逆向防护
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
Demo1:创建 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%">
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Demo1:创建 Person 类,点击事件里触发属性值的改变。
|
||||
|
||||
在内存中的结构如下图
|
||||
|
||||
<img src="./../assets/UnusedKVOIsaStructure.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/UnusedKVOIsaStructure.png" style="zoom:25%">
|
||||
|
||||
整个流程分析下:
|
||||
|
||||
@@ -30,13 +30,13 @@ Demo1:创建 Person 类,点击事件里触发属性值的改变。
|
||||
|
||||
当我们按照 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%">
|
||||
|
||||
|
||||
|
||||
Demo2:
|
||||
|
||||
<img src="./../assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
|
||||
|
||||
分析:
|
||||
|
||||
@@ -48,7 +48,7 @@ Demo2:
|
||||
|
||||
Demo3:
|
||||
|
||||
<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`
|
||||
|
||||
@@ -58,11 +58,11 @@ Demo3:
|
||||
|
||||
### 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%">
|
||||
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ Demo3:
|
||||
|
||||
### 重写 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`
|
||||
|
||||
@@ -129,7 +129,7 @@ Demo3:
|
||||
|
||||
### 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%">
|
||||
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ QA:为什么新创建的类没有 getter?
|
||||
|
||||
### 修改成员变量的值可以触发 KVO 吗
|
||||
|
||||
<img src="./../assets/KVOCannotInvokeWhenChangeIvarDirectly.png" style="zoom:25%">
|
||||
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOCannotInvokeWhenChangeIvarDirectly.png" style="zoom:25%">
|
||||
|
||||
我们将 Person 类的成员变量暴露出来,在点击事件里修改,发现不能触发 KVO。
|
||||
|
||||
@@ -158,7 +158,7 @@ QA:如何手动触发?
|
||||
|
||||
手动调用 `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%">
|
||||
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ QA:如何手动触发 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。
|
||||
|
||||
@@ -205,7 +205,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`
|
||||
|
||||
@@ -260,7 +260,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%">
|
||||
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ Apple 文档告诉我们:被观察对象的 `isa指针` 会指向一个中间
|
||||
|
||||
- 键值观察通知依赖于 NSObject 的两个方法:`willChangeValueForKey:、didChangeValueForKey:` 。在一个被观察属性改变之前,调用 `willChangeValueForKey:` 记录旧的值。在属性值改变之后调用 `didChangeValueForKey:`,从而 `observeValueForKey:ofObject:change:context:` 也会被调用。
|
||||
|
||||

|
||||

|
||||
|
||||
为什么要选择是继承的子类而不是分类呢?
|
||||
子类在继承父类对象,子类对象调用调方法的时候先看看当前子类中是否有方法实现,如果不存在方法则通过 isa 指针顺着继承链向上找到父类中是否有方法实现,如果父类种也不存在方法实现,则继续向上找...直到找到 NSObject 类为止,系统会抛出几次机会给程序员补救,如果未做处理则奔溃
|
||||
|
||||
Reference in New Issue
Block a user