KVO简析
為什么80%的碼農(nóng)都做不了架構師?>>> ??
學習并使用KVO有段時間了,在之前也簡單的介紹了KVO機制,
這種機制提供了監(jiān)聽某些類屬性變化的機制.在MVC中,簡單的說,通過監(jiān)聽M的變化,可以及時更新V.因為監(jiān)聽屬性明確,當有變化時就直接傳遞到觀察者.
考慮這樣一種情況:請求某網(wǎng)站的rss,并將內容解析出來在tableview中顯示出來.因為網(wǎng)絡請求以及數(shù)據(jù)解析需要時間,如果我們把獲得的全部數(shù)據(jù)解析后再顯示出來,在用戶體驗上就會非常不好:用戶啟動程序后,風火輪可能需要轉很久,然后突然就冒出來一大堆的數(shù)據(jù).
改進的方法之一就是使用KVO,當有一條數(shù)據(jù)解析好后,就解析出來,直到全部數(shù)據(jù)解析完.具體的實現(xiàn)步驟:
可是某一天,突然有人問我:為什么需要使用KVO啊,你使用KVO代碼量未必會減少,并且更新UI的操作我完全可以在數(shù)據(jù)有變化時進行”手工”操作啊.
當時我確實被問到了,可是細細想來KVO還是有不少”好處”的:
?
k-v-o 掃盲
對kvo/kvc做了簡單的介紹,可作為入門讀物。
有些術語描述不夠精確請指正。
歡迎討論。
Kvo是Cocoa的一個重要機制,他提供了觀察某一屬性變化的方法,極大的簡化了代碼。這種觀察-被觀察模型適用于這樣的情況,比方說根據(jù)A(數(shù)據(jù)類)的某個屬性值變化,B(view類)中的某個屬性做出相應變化。對于推崇MVC的cocoa而言,kvo應用的地方非常廣泛。(這樣的機制聽起來類似Notification,但是notification是需要一個發(fā)送notification的對象,一般是notificationCenter,來通知觀察者。而kvo是直接通知到觀察對象。)
適用kvo時,通常遵循如下流程:
1 注冊:
-(void)addObserver:(NSObject?*)anObserver forKeyPath:(NSString?*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context
?
keyPath就是要觀察的屬性值,options給你觀察鍵值變化的選擇,而context方便傳輸你需要的數(shù)據(jù)(注意這是一個void型)
2 實現(xiàn)變化方法:
-(void) observeValueForKeyPath:(NSString?*)keyPath ofObject:(id)object
change:(NSDictionary?*)change context:(void*)context
change里存儲了一些變化的數(shù)據(jù),比如變化前的數(shù)據(jù),變化后的數(shù)據(jù);如果注冊時context不為空,這里context就能接收到。
是不是很簡單?kvo的邏輯非常清晰,實現(xiàn)步驟簡單。
說了這么多,大家都要躍躍欲試了吧。可是,在此之前,我們還需要了解KVC機制。其實,知道了kvo的邏輯只是幫助你理解而已,要真正掌握的,不在于kvo的實現(xiàn)步驟是什么,而在于KVC,因為只有符合KVC標準的對象才能使用kvo(強烈推薦要使用kvo的人先理解KVC)。
KVC是一種間接訪問對象屬性(用字符串表征)的機制,而不是直接調用對象的accessor方法或是直接訪問成員對象。
key就是確定對象某個值的字符串,它通常和accessor方法或是變量同名,并且必須以小寫字母開頭。Key path就是以“.”分隔的key,因為屬性值也能包含屬性。比如我們可以person這樣的key,也可以有key.gender這樣的key path。
獲取屬性值時可以通過valueForKey:的方法,設置屬性值用setValue:forKey:。與此同時,KVC還對未定義的屬性值定義了valueForUndefinedKey:,你可以重載以獲取你要的實現(xiàn)(補充下,KVC定義載NSKeyValueCoding的非正式協(xié)議里)。
在O-C 2.0引入了property,我們也可以通過.運算符來訪問屬性。下面直接看個例子:
@property NSInteger number;
instance.number?=3;
[instance setValue:[NSNumber numberWithInteger:3] forKey:@"number"];
?
注意KVC中的value都必須是對象。
以上介紹了通過KVC來獲取/設置屬性,接下來要說明下實現(xiàn)KVC的訪問器方法(accessor method)。Apple給出的慣例通常是:
-key:,以及setKey:(使用的name convention和setter/getter命名一致)。對于未定義的屬性可以用setNilValueForKey:。
至此,KVC的基本概念你應該已經(jīng)掌握了。之所以是基本,因為只涉及到了單值情況,kvc還可以運用到對多關系,這里就不說了,留給各位自我學習的空間
接下來,我們要以集合為例,來對掌握的KVC進行一下實踐。
之所以選擇array,因為在ios中,array往往做為tableview的數(shù)據(jù)源,有這樣的一種情況:
?假設我們已經(jīng)有N條數(shù)據(jù),在進行了某個操作后,有在原先的數(shù)據(jù)后多了2條記錄;或者對N中的某些數(shù)據(jù)進行更新替換。不使用KVC我們可以使用reloadData方法或reloadRowsAtIndexPaths。前一種的弊端在于如果N很大消耗就很大。試想你只添加了幾條數(shù)據(jù)卻要重載之前N數(shù)據(jù)。后一種方法的不足在于代碼會很冗余,你要一次計算各個indexPath再去reload,而且還要提前想好究竟在哪些情況下會引起數(shù)據(jù)更新,
倘若使用了KVC/kvo,這樣的麻煩就迎刃而解了,你將不用關心追加或是更新多少條數(shù)據(jù)。
下面將以添加數(shù)據(jù)為例,說明需要實現(xiàn)的方法:
實現(xiàn)insertObject:inKeyAtIndex:或者insertKey:atIndexes。同時在kvo中我們可以通過change這個dictionary得知發(fā)生了哪種變化,從而進行相應的處理。
?
轉載于:https://my.oschina.net/hujian/blog/703454
總結
- 上一篇: 7 款顶级开源 BI(商务智能)软件和报
- 下一篇: Android开发过程中的部分经验总结