IOS開發(39)之KVC KVO KVB

來源:互聯網
上載者:User

KVC(Key Value Coding)

KVO(Key Value Observing)

KVB(Key Value Binding)

KVO是Cocoa的一個重要機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。這種觀察-被觀察模型適用於這樣的情況,比方說根據A(數 據類)的某個屬性值變化,B(view類)中的某個屬性做出相應變化。對於推崇MVC的cocoa而言,kvo應用的地方非常廣泛。(這樣的機制聽起來類 似Notification,但是notification是需要一個發送notification的對象,一般是 notificationCenter,來通知觀察者。而kvo是直接通知到觀察對象。)

when use KVO,it usually follows below:

1 註冊:

- (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context
keyPath就是要觀察的屬性值,options給你觀察索引值變化的選擇,而context方便傳輸你需要的資料(注意這是一個void型)

2 實現變化方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void*)context
change裡儲存了一些變化的資料,比如變化前的資料,變化後的資料;如果註冊時context不為空白,這裡context就能接收到。

是不是很簡單?kvo的邏輯非常清晰,實現步驟簡單。

說了這麼多,大家都要躍躍欲試了吧。可是,在此之前,我們還需要瞭解KVC機制。其實,知道了kvo的邏輯只是協助你理解而已,要真正掌握的,不在於kvo的實現步驟是什麼,而在於KVC,因為只有符合KVC標準的對象才能使用KVO(強烈推薦要使用KVO的人先理解KVC)。

KVC是一種間接訪問對象屬性(用字串表徵)的機制,而不是直接調用對象的accessor方法或是直接存取成員對象。

key就是確定對象某個值的字串,它通常和accessor方法或是變數同名,並且必須以小寫字母開頭。

Key path就是以“.”分隔的key,property can be object whick also contains property。比如我們可以person這樣的key,也可以有key.gender這樣的key path。

(setValue:forKey,valueForKey:)、(setValue:forKeyPath,valueForKeyPath:)


擷取屬性值時可以通過valueForKey:的方法,設定屬性值用setValue:forKey:。與此同時,KVC還對未定義的屬性值定義了 valueForUndefinedKey:,你可以重載以擷取你要的實現(補充下,KVC定義載NSKeyValueCoding的非正式協議裡)。

在O-C 2.0引入了property,我們也可以通過.運算子來訪問屬性。下面直接看個例子:

@property NSInteger number;

instance.number =3;
[instance setValue:[NSNumber numberWithInteger:3] forKey:@"number"];
注意KVC中的value都必須是對象。

以上介紹了通過KVC來擷取/設定屬性,接下來要說明下實現KVC的訪問器方法(accessor method)。Apple給出的慣例通常是:

-key:,以及setKey:(使用的name convention和setter/getter命名一致)。對於未定義的屬性可以用setNilValueForKey:。

至此,KVC的基本概念你應該已經掌握了。之所以是基本,因為只涉及到了單值情況,kvc還可以運用到對多關係,這裡就不說了,留給各位自我學習的空間

接下來,我們要以集合為例,來對掌握的KVC進行一下實踐。

之所以選擇array,因為在ios中,array往往做為tableview的資料來源,有這樣的一種情況:

 假設我們已經有N條資料,在進行了某個操作後,有在原先的資料後多了2條記錄;或者對N中的某些資料進行更新替換。不使用KVC我們可以使用 reloadData方法或reloadRowsAtIndexPaths。前一種的弊端在於如果N很大消耗就很大。試想你只添加了幾條資料卻要重載之前N資料。後一種方法的不足在於代碼會很冗餘,你要一次計算各個indexPath再去reload,而且還要提前想好究竟在哪些情況下會引起資料更新,

倘若使用了KVC/kvo,這樣的麻煩就迎刃而解了,你將不用關心追加或是更新多少條資料。

下面將以添加資料為例,說明需要實現的方法:

實現insertObject:inKeyAtIndex:或者insertKey:atIndexes。同時在kvo中我們可以通過change這個dictionary得知發生了哪種變化,從而進行相應的處理。

新增加一個例子:點擊下載

 

1 .Person類
@implementation Person @synthesize name,age;//屬性name 將被監視
-(void) changeName {     name=@"changeName directly"; } @end   2.PersonMonitor類  監視了name屬性 @implementation PersonMonitor  - (void)observeValueForKeyPath:(NSString *)keyPath                       ofObject:(id)object                         change:(NSDictionary *)change                        context:(void *)context {     if ([keyPath isEqual:@"name"])     {         NSLog(@"change happen, old:%@   new:%@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);     } } @end   3測試代碼     //初始化被監視對象     Person *p =[[Person alloc] init];    //監視對象    PersonMonitor *pm= [[PersonMonitor alloc]init];     [p addObserver:pm forKeyPath:@"name" options:(NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld) context:nil];    //測試前的資料     NSLog(@"p.name is %@",p.name);     //通過setvalue 的方法,PersonMonitor的監視將被調用   [p setValue:@"name kvc" forKey:@"name"];   //查看設定後的值    NSLog(@"p name get by kvc is %@",[p valueForKey:@"name"]);  //效果和通過setValue 是一致的     p.name=@"name change by .name=";   //通過person自己的函數來更改name       [p changeName];    結果是 輸出 2011-07-03 16:35:57.406 Cocoa[13970:903] p.name is name 2011-07-03 16:35:57.418 Cocoa[13970:903] change happen, old:name   new:name kvc 2011-07-03 16:35:57.420 Cocoa[13970:903] p name get by kvc is name kvc 2011-07-03 16:35:57.421 Cocoa[13970:903] change happen, old:name kvc   new:name change by .name= 最後一次修改是直接修改  所以沒法產生通知 KVB
兩個基本方法

1:為對象添加觀察者Observer

addObsever:forKeyPath:options:context;

2:觀察者Observer收到資訊的處理函數

obseveValueForKeyPath:ofObject:change:context;

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.