KVC
鍵值編碼(Key-Value Coding)是Cocoa的一個(gè)特性,它允許你通過(guò)對(duì)象名設(shè)置和獲取對(duì)象的值。
KVC特性
- 如果嘗試給一個(gè)并不存在于你定義的類的鍵設(shè)置一個(gè)值,該KVC系統(tǒng)將會(huì)拋出一個(gè)異常,因?yàn)檫\(yùn)行時(shí)不知道將該值存儲(chǔ)在哪里。
- 在KVC中沒有訪問(wèn)保護(hù),當(dāng)私有變量被訪問(wèn)時(shí),KVC依然有效。
KVC不是旨在更換訪問(wèn)方法,而是提供一個(gè)更為靈活的方式設(shè)置和獲取對(duì)象的值。
KVO
在MVC模式下,控制器如何得知何時(shí)更新視圖?有兩種選項(xiàng):
- 反復(fù)檢查模型,觀察是否有任何更改。
- 等待模型向控制器發(fā)送通知。
第一種選項(xiàng)的實(shí)現(xiàn)最簡(jiǎn)單,創(chuàng)建一個(gè)定時(shí)器,定期獲取模型中的最新值,并將其提供給視圖。(浪費(fèi)CPU資源)
要解決此問(wèn)題,Cocoa提供了一種功能,KVO。KVO允許對(duì)象注冊(cè)為當(dāng)另一個(gè)對(duì)象更改它的一個(gè)屬性的值時(shí)收到通知。
KVO有助于簡(jiǎn)化注冊(cè)通知的過(guò)程以及通知任何需要被告知變化的對(duì)象。任何對(duì)象的任何屬性都可以被觀察,只要該屬性的名稱符合KVO。(前提是執(zhí)行了setter方法或者使用了KVC賦值)。
添加觀察者:
[self.model addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
當(dāng)屬性發(fā)生變化時(shí),系統(tǒng)會(huì)回調(diào)該方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"title"] && (object == self.model)) {
// 獲取新值,更新label。
NSString *newTitle = [change objectForKey:NSKeyValueChangeNewKey];
self.textLabel.text = newTitle;
NSString *oldTitle = [change objectForKey:NSKeyValueChangeOldKey];
NSLog(@"%@", oldTitle);
}
}
另外,如果不使用OC屬性,或者重寫了一個(gè)屬性的setter方法,則需要手動(dòng)通知系統(tǒng)所做的更改。
- (void)setTitle:(NSString *)title {
[self willChangeValueForKey:@"title"];
_title = title;
[self didChangeValueForKey:@"title"];
}