鍵路徑 在一個給定的實體中,同一個屬性的所有值具有相同的數據類型。 鍵-值編碼技術用於進行這樣的查找—它是一種間接訪問對象屬性的機制。 - 鍵路徑是一個由用點作分隔符的鍵組成的字元串,用於指定一個連接在一起的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每個鍵的值也是相對於其前面的性質。 ...
鍵路徑
-
在一個給定的實體中,同一個屬性的所有值具有相同的數據類型。
-
鍵-值編碼技術用於進行這樣的查找—它是一種間接訪問對象屬性的機制。 - 鍵路徑是一個由用點作分隔符的鍵組成的字元串,用於指定一個連接在一起的對象性質序列。第一個鍵的性質是由先前的性質決定的,接下來每個鍵的值也是相對於其前面的性質。
-
鍵路徑使您可以以獨立於模型實現的方式指定相關對象的性質。通過鍵路徑,您可以指定對象圖中的一個任意深度的路徑,使其指向相關對象的特定屬性。
鍵值編碼KVC
-
鍵值編碼是一種間接訪問對象的屬性使用字元串來標識屬性,而不是通過調用存取方法,直接或通過實例變數訪問的機制,非對象類型的變數將被自動封裝或者解封成對象,很多情況下會簡化程式代碼;
-
KVC的缺點:一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設置的鍵、鍵路徑進行錯誤檢查,且執行效率要低於合成存取器方法和自定的 setter 和 getter 方法。因為使用 KVC 鍵值編碼,它必須先解析字元串,然後在設置或者訪問對象的實例變數。
鍵值觀察KVO
-
鍵值觀察機制是一種能使得對象獲取到其他對象屬性變化的通知 ,極大的簡化了代碼。
-
實現 KVO 鍵值觀察模式,被觀察的對象必須使用 KVC 鍵值編碼來修 改它的實例變數,這樣才能被觀察者觀察到。因此,KVC是KVO的基礎。
Demo
比如我自定義的一個button
1 2 3 4 5 6 7 8 |
[self addObserver:self forKeyPath:@ "highlighted" options:0 context:nil];
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@ "highlighted" ] ) {
[self setNeedsDisplay];
}
}
|
對於系統是根據keypath去取的到相應的值發生改變,理論上來說是和kvc機制的道理是一樣的。
KVC機制通過key找到value的原理。
-
當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程式會自動試圖通過下麵幾種不同的方式解析這個調用。
-
首 先查找對象是否帶有 someKey 這個方法,如果沒找到,會繼續查找對象是否帶有someKey這個實例變數(iVar),如果還沒有找到,程式會繼續試圖調用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現的話,程式會拋出一個NSUndefinedKeyException 異常錯誤。
-
補充:KVC查找方法的時候,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方法, 前面加一個get,或者_someKey以_getsomeKey這幾種形式。同時,查找實例變數的時候也會不僅僅查找someKey這個變數,也會查找 _someKey這個變數是否存在。
-
設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最後的機會響應這個請求。
在 Objective-C 中如何實現 KVO
-
註冊觀察者(註意:觀察者和被觀察者不會被保留也不會被釋放)
1 2 3 |
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context;
|
-
接收變更通知
1 2 |
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
|
-
移除對象的觀察者身份
1 2 |
- (void)removeObserver:(NSObject *)observer
forKeyPath:(NSString *)keyPath;
|
-
KVO中誰要監聽誰註冊,然後對響應進行處理,使得觀察者與被觀察者完全解耦。KVO只檢測類中的屬性,並且屬性名都是通過NSString來查找,編譯器不會檢錯和補全,全部取決於自己。