iOS學習筆記8 – KVO與KVC

來源:互聯網
上載者:User

KVO和KVC分別是Key-Value Observing和Key-Value Coding的簡稱。想到這個話題是因為現在我寫的tableView的更新是每隔數秒的輪詢,在考慮是不是需要用個類似觸發更新的機制。這自然就想到了觀察者模式。

搜尋Objective-c的觀察者模式,發現在http://stackoverflow.com/questions/165790/whats-the-nicest-way-to-do-observer-observable-in-objective-c-iphone-version 中提到有兩種方式可以實現:NSNotificationCenter和KVO。那個回答裡形容Notification是較為古老而重型的。。。雖然我也稍微研究過,不過還是作為下次的話題吧。 

 

1. KVC

咦,不是要說KVO嗎?為什麼先要說KVC?Mac Developer Library說KVC是KVO的準備知識。好吧,先來看看KVC。

KVC是一種非直接存取對象屬性的機制。什麼是直接存取?get和set。

用省略過頭的話來解釋,KVC就是通過key來擷取value。

有點像Dictionary?嗯,從某種意義上來說是,但遠遠不止。

在Objective-C下,也有一個字典類NSDictionary,可以通過objectForKey方法來擷取某個key所對應的value。但KVC可以在所有類中使用valueForKey這個方法,來擷取某個property(key)的值(value)。

來看看代碼範例。例如有這麼一個類:

@interface TestClass : NSObject@property NSInteger integerProperty;@property TestClass *linkedInstance;@end

可以使用傳統的set來賦值,例如:

    TestClass *anotherInstance = [[TestClassalloc] init];    myInstance.linkedInstance = anotherInstance;    myInstance.integerProperty = 2;

不過也可以用kvc來賦值:

    TestClass *anotherInstance = [[TestClass alloc] init];    myInstance.linkedInstance = anotherInstance;    [myInstance setValue:@2forKeyPath:@"linkedInstance.integerProperty"];

從這個角度上來說,KVC類似於.NET中反射的部分功能。

如上所述,要通過KVC取值,可以通過valueForKey。

由於是語言層級的功能,所以KVC能實現的功能挺強大。例如:

根據index來擷取一個或數個:objectAtIndex, objectsAtIndexes, count, -get<Key>:range:

增刪改:insertObject, insertObjects,removeObjectAtIndex, replaceObjectAtIndex, 

 

2. KVO

KVO的作用是允許某個對象得知其他對象的某個屬性發生了改動。在MVC的model和controller層之間的互動中應用得特別廣泛。

實現KVO需要三步:

1) 明確通知對象和被通知對象

例如:如果存款發生了變更,比如被提取了5000元,那麼賬戶所有人就需要被告知。這個情境中,通知對象就是銀行賬戶,被通知對象就是賬戶所有人

 

2) 被通知對象在通知對象中,註冊對某個屬性的觀察者

文法為:addObserver:forKeyPath:options:context:

對於上面那個例子,所有者就需要在賬戶執行個體裡註冊一個觀察者。

代碼範例:

[account addObserver:inspector

              forKeyPath:@"openingBalance"

                 options:(NSKeyValueObservingOptionNew |

                          NSKeyValueObservingOptionOld)

                 context:NULL];

其中option的參數表示需要得知這個屬性更改前和更改後的值。

另外,可以添加,自然也可以用removeObserver移除。

 

3) 被通知對象(觀察者)實現observeValueForKeyPath方法

這個方法是用來實現當被通知後,觀察者會做些啥反應

對於上面那個例子,如果觀察者判斷自己有沒有進行過提款或購物操作,然後決定是不是警示?

代碼範例:

- (void)observeValueForKeyPath:(NSString *)keyPath                      ofObject:(id)object                        change:(NSDictionary *)change                       context:(void *)context {    if ([keyPath isEqual:@"openingBalance"]) {        [openingBalanceInspectorField setObjectValue:         [change objectForKey:NSKeyValueChangeNewKey]];    }    /*     Be sure to call the superclass's implementation *if it implements it*.     NSObject does not implement the method.     */    [superobserveValueForKeyPath:keyPath                         ofObject:object                           change:change                          context:context];}

 

 

參考資料:

Key-Value Coding Programming Guide

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html%23//apple_ref/doc/uid/10000107-SW1

 

Key-Value Observing Programming Guide

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html%23//apple_ref/doc/uid/10000177-BCICJDHA

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.