- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
DSKeyValueProperty * property = DSKeyValuePropertyForIsaAndKeyPath(object_getClass(self),keyPath);
Class isaForAutonotifying = [property isaForAutonotifying];
if(isaForAutonotifying) {
Class cls = object_getClass(self);
// 把當(dāng)前類的isa指向動(dòng)態(tài)創(chuàng)建的子類
if(cls != isaForAutonotifying) {
object_setClass(self,isaForAutonotifying);
}
}
}
- (Class)isaForAutonotifying {
// 動(dòng)態(tài)創(chuàng)建一個(gè)子類
Class subClass = objc_allocateClassPair(originalClass, newClassName, sizeof(DSKeyValueNotifyingInfo));
objc_registerClassPair(subClass);
// 為子類添加四個(gè)方法
class_addMethod(subClass, @selector(_isKVOA), NSKVOIsAutonotifying, encoding);
class_addMethod(subClass, @selector(dealloc), NSKVODeallocate, encoding);
class_addMethod(subClass, @selector(class), NSKVOClass, encoding);
class_addMethod(subClass, @selector(setXXX), _NSSetObjectValueAndNotify, encoding);
return subClass;
}
Class NSKVOClass(id object, SEL selector) {
// 返回調(diào)用父類的class方法
return [originalClass class];
}
void _NSSetObjectValueAndNotify(id object,SEL selector, id value) {
NSKeyValueWillChange();
// keypath嵌套的情況下調(diào)用下面兩句
[changingRelationshipObject removeObserver:observance forKeyPath:_keyPathFromRelatedObject];
[newRelationshipObject addObserver:observance forKeyPath:_keyPathFromRelatedObject options:option context:context];
// 調(diào)用父類的setter
IMP imp = class_getMethodImplementation(info->originalClass, selector);
setValueWithImplementation(imp);
NSKeyValueDidChange();
}
void NSKeyValueDidChange(id object, id keyOrKeys, BOOL isASet,DSKVODidChangeDetailSetupFunc didChangeDetailSetupFunc, DSKVODidChangeNotificationPopFunc didChangeNotificationPopFunc, void *popInfo) {
遍歷所有的observer {
[observer observeValueForKeyPath:keyPath ofObject:object change:changeDictionary context:context];
}
}
KVO底層偽代碼
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 需求背景: 我們的App中有好多彈窗和浮層,活動(dòng)、更新、新手引導(dǎo)、初次加載的三幀引導(dǎo)、和不同頁面不定時(shí)的彈個(gè)確...
- 當(dāng)觀察某對象 A 時(shí),KVO 機(jī)制動(dòng)態(tài)創(chuàng)建一個(gè)對象A當(dāng)前類的子類,并為這個(gè)新的子類重寫了被觀察屬性 keyPath...
- 一、KVO的理解 1.KVO(鍵值監(jiān)聽)即Key-Value-Observing,是Objective-C對觀察者...
- 我們都知道蘋果的KVO可以為我們提供觀察屬性的方法,它可以實(shí)現(xiàn)監(jiān)聽屬性的改變并得到通知。既然蘋果沒有給我們開源,那...
- KVO底層實(shí)現(xiàn)原理 KVO是基于runtime機(jī)制實(shí)現(xiàn)的 當(dāng)某個(gè)類的屬性對象第一次被觀察時(shí),系統(tǒng)就會在運(yùn)行期動(dòng)態(tài)地...