MJiOS底層筆記--KVO本質

本文屬筆記性質,主要針對本身理解不太透徹的地方進行記錄。ios

推薦系統直接學習小碼哥iOS底層原理班---MJ老師的課確實不錯,強推一波。bash


NSKVONotifying_Person

KVO時,將被監聽的對象isa指針動態修改爲新類NSKVONotifying_Person函數

在對一個(Person)instance對象使用KVO進行監聽時,系統利用RuntimeAPI動態生成一個(Person的)子類,而且讓(Person)instance對象的isa指向這個全新的子類學習


NSKVONotifying_Person內部

  • isa

指向NSKVONotifying_Person內部元類,提供方法實現ui

  • superClass、class

爲了掩蓋NSKVONotifying_Person的存在,修改了這兩個方法。使其結果與Person類返回的相同。spa

Class cls = object_getClass(self.person1);
Class spcls =class_getSuperclass(cls);
NSLog(@"object_getClass==%@",cls);
NSLog(@"class==%@",[self.person1 class]);
NSLog(@"class_getSuperclass==%@",spcls);
NSLog(@"superclass==%@",[self.person1 superclass]);

//打印
object_getClass==NSKVONotifying_MJPerson
class==MJPerson
class_getSuperclass==MJPerson
superclass==NSObject
複製代碼
  • dealloc

作一些收尾工做3d

  • isKVOA

鑑定是否被KVO指針


_NSSetXXXValueAndNotify

被監聽對象屬性的set方法IMP指針所指方法code

Foundation下的一個C語言函數,當調用被監聽對象屬性的set方法時,實際上將會調用這個C語言方法。cdn

其內部將會調用一系列方法修改爲員變量而且觸發監

- (void)setAge:(int)age
{
    _NSSetIntValueAndNotify();
}

// 僞代碼
void _NSSetIntValueAndNotify()
{
    [self willChangeValueForKey:@"age"];
    [super setAge:age];
    [self didChangeValueForKey:@"age"];
}
複製代碼

willChangeValueForKey && didChangeValueForKey

觸發監聽的方法。能夠手動調用以主動觸發監聽

  • 只有被監聽的屬性被修改,纔會調用這個方法

未被監聽的屬性修改不會觸發

  • 兩個方法須要配對使用

只調用didChangeValueForKey不會觸發監聽


KVO觸發條件

經過set方法爲屬性賦值

直接修改爲員變量不會觸發監聽

KVC與KVO

KVC賦值是能夠觸發KVO的

而且,KVC內部實現了通知邏輯(willChangeValueForKey&&didChangeValueForKey)。即便沒有實現set方法,也能被通知。

KVC賦值過程

其中accessInstanceVariablesDirectly默認返回YES

KVC取值過程

其中accessInstanceVariablesDirectly默認返回YES

相關文章
相關標籤/搜索