iOS runtime 筆記三 — 自定義KVO 的實現(xiàn)邏輯

語言描述

KVO 的實質(zhì). ---- 官方文檔上面對于 KVO 實現(xiàn)調(diào)用的描述,也稱作,調(diào)用了 runtime 的isa swizzling.實質(zhì)上是將類進行過了替換.
假設我們定義了一個Person類,包含有name這個屬性

@interface Person:NSObject
@property (nonatomic,copy) NSString *name;
@end

ViewController中添加觀察者,觀察name值的變化.
系統(tǒng)會動態(tài)的創(chuàng)建一個Person的子類 NSKVONotifying_Person. 并重寫namesetter方法

[self willChangeValueForKey:@"name"]; // 調(diào)用 observer 告知改變舊值
[self setName:name];
[self didChangeValueForKey:@"name"]; // 調(diào)用 observer 告知改變成新值

重寫之后,用這個類去替換原先的Person類.這樣,在 Person調(diào)用 person.name = @"someName";時,KVO 操作對應的內(nèi)容就會被調(diào)用.


Hank 公開課筆記中的內(nèi)容

關于自定義 KVO

  • 首先,要動態(tài)創(chuàng)建一個Person類的子類.
-(void)FF_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context {
    /*
     1.動態(tài)添加一個類
     */
    NSString * oldClassName = NSStringFromClass([self class]);
    NSString * newClassName = [@"MyKVO_" stringByAppendingString:oldClassName];
    const char * newName = [newClassName UTF8String];
    //定義一個類
    Class subClass = objc_allocateClassPair([self class], newName, 0); // 動態(tài)創(chuàng)建一個類,繼承于[self Class],類名為 newName
        //注冊這個類
    objc_registerClassPair(subClass);
  
    //改變isa指針!! 讓方法調(diào)用者,調(diào)用到當前的自定義方法.(可以看做原先 isa 指向 person 類,現(xiàn)在讓他指向 subClass)
    object_setClass(self, subClass);
    
    //重寫setAge方法!! 
    /*
     說明, 我們平日里,在子類中調(diào)用方法,(假設 A有一個方法 methodA, a 是 A 的子類, a  是可以去調(diào)用 methodA),實質(zhì)上是先在 SEL 列表中查找這個 methodA 方法,如果找不到, 繼續(xù)去尋找他的父類 A 的 SEL 中是否包含有這個方法.找到后去調(diào)用.
     
     因此,實際上子類本身是不包含 `setAge`這個方法的.如果直接調(diào)用,那么實質(zhì)上去調(diào)用父類的這個方法,這不是我們想要的.因為這里我們需要去重寫這個`setAge`的方法.
    */
    class_addMethod(subClass, @selector(setAge:), (IMP)setAge, "v@:@");
}


//有默認參數(shù)!!  RAC
void setAge(id self,SEL _cmd,int age){
    NSLog(@"進入");
    id class = [self class];
    //讓自己指向父類
    object_setClass(self, class_getSuperclass([self class]));
    objc_msgSend(self, @selector(setAge:),age);
    object_setClass(self, class);
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容