KVO與KVC簡單理解

KVO與KVC簡單理解

///////////////////////////////////////我是該死的分割線/////////////////////////

KVO,即:Key-Value Observing,翻譯過來就是鍵--值--觀察.它提供一種機制,當指定的對象的屬性被修改后,則對象就會接受到通知。簡單的說就是每次指定的被觀察的對象的屬性被修改后,KVO就會自動通知相應的觀察者了。

系統框架已經支持KVO,所以我們要做的就是如何用了.

1. 注冊,指定被觀察者的屬性,//誰要觀察,誰的屬性改變通知你.

[stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

//對象 ?添加觀察者:我自己 哪個屬性:price屬性 可選項:模式|模式 ?上下文:空

這樣就把注冊,指定觀察者屬性都做完了

2. 實現回調方法//通知了你,你得做點事吧.

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context

{

if([keyPath isEqualToString:@"price"])

{

myLabel.text = [stockForKVO valueForKey:@"price"];

}

}

//在這個方法里寫通知你之后干的事,像例子說的那樣,先判斷是不是這個屬性,然后再賦值.判斷這一步不能少,如果同時好多人在觀察,可能搞混淆.這里得引入和通知的區別了.

//KVO與通知區別:

通知:是一種廣播機制,在實踐發生的時候,通過通知中心對象,一個對象能夠為所有關心這個時間發生的對象發送消息,兩者都是觀察者模式,不同在于KVO是被觀察者直接發送消息給觀察者,是對象間的直接交互,通知則是兩者都和通知中心對象交互,對象之間不知道彼此

KVO使用:被觀察著發生addobserver:forkeyPath:options:context:方法來添加觀察者.然后只要被觀察者的keypath值發生變化(注意單純改變值不會調用此方法,只有通過getter和sett來改變值才會觸發KVO),就會在觀察者里調用方法observerValueForKeyPath:ofobject:change:context:因此實現此方法來對KVO發出的通知做出響應.

這些代碼都是秩序在觀察者里進行實現,被觀察者不用添加任何代碼,所以誰要監聽誰要注冊,然后對響應進行處理即可,使得觀察者與被觀察者完全解耦,運用很靈活很簡便,但是KVO只能檢測類中屬性,并且屬性名都是通過NSString來查找,編譯器不會幫你檢測對錯和補全,純手敲會比較容易出錯

通知的使用:通知的發出是由通知中心來統一發出,而不同通知通過唯一標示名notifcationName來區分,標示名由發送通知的類來起.首先被觀察者自己在必要的方法A里,通過方法postNotificationName:object:發出通知notificationName這樣發送通知著這邊的工作就完成了,每次A被調用,就會發送一次通知notificationName

然后誰要監聽A的變化,就通過[NSNotificationCenter defaultCenter] 的方法addobserver:sslector:name:object為觀察者注冊監聽name為notificationNmae的通知.

每次發出name為notificationNmae的通知時,注冊監聽后的觀察著就會調用其自己定義的方法notificationselector來進行相應

NSNotification的特點,就是需要被觀察者先主動發出通知,然后觀察者注冊監聽后,再來進行響應,比KVO多了發送通知的一步,但是其優點是監聽不局限屬性的變化,還可以對多種多樣的狀態變化進行監聽,監聽范圍廣,使用靈活.

3. 移除觀察//不會自動移除,需要手動移除

增加觀察與取消觀察是成對出現的,所以需要在最后的時候,移除觀察者

///////////////////////////////////////我是該死的分割線//////////////////////////

KVC是KeyValueCoding的簡稱,翻譯過來是鍵值編碼,它是一種可以直接通過字符串的名字(key)來訪問類屬性(實例變量)的機制。而不是通過調用Setter、Getter方法(點語法)訪問。

當使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)時,KVC是關鍵技術。

//

關鍵方法定義在:NSKeyValueCodingprotocol

The NSKeyValueCoding informal protocol defines a mechanism by which you can access the properties of an object indirectly by name (or key), rather than directly through invocation of an accessor method or as instance variables. Thus, all of an object’s properties can be accessed in a consistent manner.

這個鍵值編碼非正式協議定義了一個機制通過你可以間接的獲取一個對象的屬性通過名字(或者叫key),而不是直接通過調用訪問器方法或者實例變量.因此,一個對象的所有屬性可以被存取用一個通用的方式.

The basic methods for accessing an object’s values are setValue:forKey:, which sets the value for the property identified by the specified key, and valueForKey:, which returns the value for the property identified by the specified key. The default implementation uses the accessor methods normally implemented by objects (or to access instance variables directly if need be).

這個基本方法對于訪問一個對象的值是 setValue:forKey用來設置值對于可識別的屬性通過規定的key,和valueForKey用來返回一個值對于可識別的屬性通過規定的key.這個默認的實現使用了訪問器方法正常的實現通過對象(或者通過實例變量如果需要的話).

Default Search Pattern for setValue:forKey://默認查找模式對于setValue:forKey

When the default implementation ofsetValue:forKey:is invoked for a property the following search pattern is used:

當這個默認實現setValue:forKey是屬性調用模式是使用下列搜索模式

The receiver’s class is searched for an accessor method whose name matches the pattern set:.

接收器的類去搜索訪問器方法的名字匹配這個設置模式.

If no accessor is found, and the receiver’s class method accessInstance VariablesDirectlyreturns?YES, the receiver is searched for an instance variable whose name matches the pattern, _<key>,_is<key>,<key>,is<key>,in that order.

如果訪問器方法沒有找到,而且接受方法accessInstance VariablesDirectlyreturns返回yes,接受器將會搜索實例變量的名字匹配,在這種情況下.

If a matching accessor or instance variable is located, it is used to set the value. If necessary, the value is extracted from the object as described inRepresenting Non-Object Values.

如果匹配訪問器方法或實例變量都加載了,它通常使用set the value.如果必要的話,值引出從對象像Representing Non-Object Values文檔描述的一樣.

If no appropriate accessor or instance variable is found,setValue:forUndefinedKey:is invoked for the receiver.

如果都沒有找到的話,將會喚醒setValue:forUndefinedKey給接收器.//一般拋出異常,可重寫.

//在字典轉模型里,服務器返回的數據有些不想要就重寫這個方法.

Default Search Pattern for valueForKey://默認搜索模式對于valueForKey

When the default implementation of valueForKey:is invoked on a receiver, the following search pattern is used:

//當默認實現valueForKey是調用在接收器,通常使用以下搜索模式

Searches the class of the receiver for an accessor method whose name matches the pattern get<key>,<key>,is<key>, in that order. If such a method is found it is invoked. If the type of the method's result is an object pointer type the result is simply returned. If the type of the result is one of the scalar types supported by NSNumber conversion is done and an NSNumber is returned. Otherwise, conversion is done and an NSValue is returned. Results of arbitrary types are converted to NSValue objects, not just NSPoint,NSRange,NSRect, and NSSize types).

搜索接受者類從訪問器方法的名字匹配參數get<key>,<key>,is<key>,在那種情況下.如果發現這個方法被調用了,如果這個方法飛返回類型是一個對象指針類型,這個結果簡單的返回.如果這個結果類型是數量的一種,將轉換為NSNumber返回,否則,轉換NSValue返回.任意的結果類型都是轉換成NSValue類了,不只是NSPoint,NSRange,NSRect, and NSSize types.

Otherwise (no simple accessor method is found), searches the class of the receiver for methods whose names match the patterns countOf?and objectInAtIndex:(corresponding to the primitive methods defined by the NSArray class) andAtIndexes:(corresponding to the?NSArray??method ?objectsAtIndexes:). If the countOf?method and at least one of the other two possible methods are found, a collection proxy object that responds to all NSArray methods is returned. Each NSArray message sent to the collection proxy object will result in some combination of countOf,objectInAtIndex:, andAtIndexes:messages being sent to the original receiver of?valueForKey:. If the class of the receiver also implements an optional method whose name matches the pattern get:range:that method will be used when appropriate for best performance.

否則(沒有找到簡單訪問器方法),搜索這個接受器的類從方法匹配參數countOfand objectInAtIndex(相當于去用原始方法定義在NSArray 類里)andAtIndexes(相當于去用這個NSArray方法 andAtIndexes).如果countOf方法至少一到兩個可能的方法被找到,一個集合代理對象對于所有的NSArray methods將會被返回,每一個NSArray 消息發送給集合代理對象將會返回countOf,objectInAtIndex,andAtIndexes組合.消息將要發送給valueForKey的原始接受者,如果這個接受者的類也實現一個可選方法,是名字匹配參數get:range:,那方法將會使用當合適為了做好的執行.

Otherwise (no simple accessor method or set of array access methods is found), searches the class of the receiver for a threesome of methods whose names match the patterns countOf,enumeratorOf, and memberOf:(corresponding to the primitive methods defined by theNSSet?class). If all three methods are found, a collection proxy object that responds to all NSSet methods is returned. Each NSSet message sent to the collection proxy object will result in some combination of countOf,enumeratorOf, and memberOf:messages being sent to the original receiver of?valueForKey:.

否則(訪問器方法和set of array access methods都沒有找到),搜索接收器的類將從一個三人組方法,是名字匹配模式countOf,enumeratorOf, and memberOf(相當于使用原始方法定義在NSSet類里),如果都三個方法都找到了,一個集合代理對象將會響應所有的NSSet方法并返回.每一個NSSet 消息發送給集合代理對象將會生成countOf,enumeratorOf, andmemberOf組合,消息將會被發送去這的valueForKey原始接受器.

Otherwise (no simple accessor method or set of collection access methods is found), if the receiver's class method?accessInstanceVariablesDirectly?returnsYES, the class of the receiver is searched for an instance variable whose name matches the pattern_,_is,, oris, in that order. If such an instance variable is found, the value of the instance variable in the receiver is returned. If the type of the result is one of the scalar types supported by NSNumber conversion is done and an NSNumber is returned. Otherwise, conversion is done and an NSValue is returned. Results of arbitrary types are converted toNSValueobjects, not justNSPoint,NSRange,NSRect, andNSSizetypes.

否則(沒有找到簡單訪問器方法和set of collection access methods的一種),如果接收器的類方法

accessInstanceVariablesDirectly返回yes,這個接收器的類將會搜索實例變量,是名字匹配參數

_<key>,_is<key>,<key>,is<key>,在這種情況下.如果找到了實例變量,這個實例變量的值將會被返回.如果結果的類型是數量類型的一種,將轉換成NSNumber并返回,否則,轉換為NSValue返回.任意的結果類型都是轉換成NSValue類了,不只是NSPoint,NSRange,NSRect, and NSSize types.

If none of the above situations occurs, returns a result the default implementation invokes?valueForUndefinedKey:.

如果沒有出現上述情況,返回默認實現結果調用valueForUndefinedKey.

KVC支持類對象和內建基本數據類型。

獲取值

valueForKey:,傳入NSString屬性的名字。

valueForKeyPath:,傳入NSString屬性的路徑,xx.xx形式。

valueForUndefinedKey它的默認實現是拋出異常,可以重寫這個函數做錯誤處理。

修改值

setValue:forKey:

setValue:forKeyPath:

setValue:forUndefinedKey:

setNilValueForKey:當對非類對象屬性設置nil時,調用,默認拋出異常。

一對多關系成員的情況

mutableArrayValueForKey:有序一對多關系成員??NSArray

mutableSetValueForKey:無序一對多關系成員??NSSet

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容