Objective-C之KVC、KVO,objective-ckvckvo
1,KVC(索引值編碼) Key Value Coding
1.1在C#中,可以通過字串反射來擷取對象,從而對對象的屬性進行讀寫,Object-C中有同樣的實現,通過字串(屬性名稱詞)對對象的屬性進行讀寫。
1.2KVC的操作方法由NSKeyValueCoding協議來定義,而Object對象實現該協議,所以所有的對象都具有KVC功能
動態設定:setValue:屬性值 forKey:屬性名稱 setValue: 屬性值forKeyPath:屬性路徑
動態讀取:valueForKey:屬性名稱 valueForKeyPath:屬性路徑
名詞解釋:屬性名稱(簡單路徑) 屬性路徑(複合路徑,比如A對象有一個b屬性,那麼A.b就是複合屬性)
1.3KVC動態設定規則:(假設對a進行設定)首先尋找setA方法,如果沒有setA方,則尋找_a變數,如果沒有_a變數,則尋找a變數,如果沒有a變數,則調用 setValue: forUndefinedKey:方法。對於方法和屬性,不管公有還是私人都可以設定成功
1.4KVC動態讀取規則:(假設對a進行讀取)首先讀取a方法,如果沒有a方法,則尋找_a變數,如果沒有_a變數,則尋找a變數,如果沒有a變數,則調用valueForUndefinedKey:方法。對於方法和屬性,不管公有還是私人都可以設定成功
1.5 KVC 與 對象的讀寫方法有什麼區別
1,可以通過屬性的名字直接存取屬性,而不是調用的屬性的accssor。
2,減少代碼量
for example:情境一:
People *people = [peoleArray objectAtIndex:row];
if ([[column identifier] isEqualToString:@"name"]) {
return [people name];
}
if ([[column identifier] isEqualToString:@"age"]) {
return [people age];
}
利用KVC : return [people valueForKey:[colum identifier]];
情境二:可以把一個NSDictionary 的元素直接賦值給對象的屬性。
-(id) initWithDictionary:(NSMutableDictionary*) jsonObject
{
if((self = [super init]))
{
[self init];
[self setValuesForKeysWithDictionary:jsonObject];
}
return self;
}
setValuesForKeysWithDictionary: 把NSDictionary中key對應的對象屬性設定上NSDictionary中key對應的value.
異常處理:(1)如果NSDictionary中key 與對象中屬性的名稱不一致時,我們需要 setValue: forUndefinedKey: 方法來處理沒有匹配上的屬性,否則setValuesForKeysWithDictionary:將拋出異常(NSUndefinedKeyException)
(2)如果NSDictionay 內嵌的結構比較複雜:Products{product1{count:xx, sumPrice:xx}}, product2{} ….},我們需要重寫 setValue: forKey: 方法。
情境三: 我們需要把數組裡People對象的name名字的首字母大寫,調用kvc:
return [array valueForKeyPath:@"name.capitalizedString"] (這裡是valueForKeyPath)
2,KVO(索引值監聽) Key Value Observing (觀察者模式)
2.1KVO的操作方法由NSKeyValueObserving協議來指定,NSObject對象實現了該協議,所以所有的對象都擁有KVO操作。
2.2KVO操作的方法如下:
註冊指定key路徑的監聽器: addObserver: forKeyPath: options: context:
刪除指定key路徑的監聽器:removeObserver: forKeyPath:、 removeObserver: forKeyPath: context:
監聽器回調方法: observeValueForKeyPath: ofObject: change: contenxt:
options的值說明:
NSKeyVlaueObservingOptionNew
需要補充。。。。。。。
change: 參數為NSDictionary , key 為 new 和 old
2.3KVO 與NSNotificationCenter的區別
好處:1,代碼更簡潔,不需要修改被觀察的類,永遠都是觀察者在做事情
不足:1,如果沒有observer 監聽 keyPath, removeOberser: forKeyPath: 會crash。
2,很難定位是誰監聽了對象的屬性