首先聲明 我的標題本身就是個偽命題!!!
?KVC 與 KVO 的關系 就好比雷鋒和雷峰塔的關系?
標題就是為了吸引小白和準備開噴的大牛們 ? ?真是機智如我 哈哈哈哈哈哈~~
閑言少敘 進入正題
上一篇文章我提到過 KVC ?了解 KVC 移步到這里
KVC的本質就是 (鍵值編碼)
定義: 在對象創(chuàng)建完成之后,動態(tài)(牽扯到運行時)的給對象的屬性賦值
KVC,即是指 NSKeyValueCoding,一個非正式的Protocol,提供一種機制來間接訪問對象的屬性。而不是通過調用Setter、Getter方法訪問。
預熱結束~然而我這篇文章主要想講的是 KVO
KVO 的本質就是(鍵值監(jiān)聽)
定義::Key-Value Observing,它提供一種機制,當指定的對象的屬性被修改后,則對象就會接受到通知。
直接上代碼
創(chuàng)建一個具有這三個屬性的Person類 (.h)
@interface LYPerson : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)CGFloat height;
@property(nonatomic,assign)NSInteger age;
@interface ViewController ()
@property(nonatomic,strong)LYPerson *person;
@end
@implementation ViewController
- (void)viewDidLoad {? ??
[super viewDidLoad];? ? ? ?
?LYPerson *person = [[LYPerson alloc]init];? ??
person.height = 180;? ? ? ?
?person.name =@"交警隊李哥";? ? ? ?
?person.age = 18; ??
? self.person = person;? ? ? ?
//KVO 大哥登場 ?設置監(jiān)聽
//注意 KeyPath 與 Key 雖然都是通過鍵去找值但 KeyPath 會自動尋址
//比如說我 height 屬性里還有一個"躺下的高度"或"站著的高度"(哈哈還 ?太污了)
//通過 KeyPath 就會層層深入找到 ?Key 就只能找 height 這一層
//NSKeyValueObservingOptionOld 屬性的舊值
//NSKeyValueObservingOptionNew 屬性的新值
//context 攜帶的參數
?[person addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; ? ??
//我要改值了
?? ? ? person.height = 181;
}
//keyPath?
//object 被修改屬性的類的對象
//change 返回改變前后的屬性與屬性值(字典)
//context 攜帶的參數
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context{
? ? ? ? NSLog(@"%@",change);
}
系統(tǒng)底層是怎樣實現 KVO 的
我在 person 類的 setter 方法里不也能監(jiān)聽到屬性的改變么?
確實啊 給屬性賦值就會調用 setter 方法?
那系統(tǒng)就是幫我們寫了 setter 方法么 ?
顯然不是 如果系統(tǒng)真這么干了 我們自己寫的 setter 方法跟系統(tǒng)的就會重名 直接造成程序崩潰
在萬能的百度大家可以查到 KVO 是通過創(chuàng)建一個當前類的子類 重寫子類 setter 方法
子類的 setter 方法調用 父類的 setter 方法 [super setHeight:height]
百度說的對 但不全對
可是根據 繼承與多態(tài) 的原理 我給父類屬性賦值 不會跑到子類的方法里啊
所以我們下斷點觀察一下

再下一步

細心機制的你早已發(fā)現 NSObject 里的 isa指針 改變了
指向了一個看著眼熟似曾相識的類 沒錯! ? ?那個就是系統(tǒng)幫我們創(chuàng)建的子類
最后還得驗證一下 把 isa 指針指向的類名復制 創(chuàng)建這個與系統(tǒng)幫我們創(chuàng)建類同名的類 看看會不會崩潰 在哪里崩潰

創(chuàng)建之后沒問題 因為代碼還沒運行到改變 isa 指針和創(chuàng)建子類?
咔嚓一個運行

果不其然 崩在了34行 我創(chuàng)建 KVO 監(jiān)聽的那一行