RAC學習筆記之一:KVC(一)html
原帖收藏於IT老兵博客。ios
學習RAC,須要先去了解KVC和KVO,這裏對KVC進行一下總結。web
參考蘋果官網的介紹編程
You typically use accessor methods to gain access to an object’s properties. A get accessor (or getter) returns the value of a property. A set accessor (or setter) sets the value of a property. In Objective-C, you can also directly access a property’s underlying instance variable. Accessing an object property in any of these ways is straightforward, but requires calling on a property-specific method or variable name. As the list of properties grows or changes, so also must the code which accesses these properties. In contrast, a key-value coding compliant object provides a simple messaging interface that is consistent across all of its properties.
Key-value coding is a fundamental concept that underlies many other Cocoa technologies, such as key-value observing, Cocoa bindings, Core Data, and AppleScript-ability. Key-value coding can also help to simplify your code in some cases.app
一言以蔽之,這一段的意思是編寫傳統的獲取和設置屬性的方法(getter和setter)會隨着屬性值的增長而變得愈來愈枯燥,因此OC提供了一種直接根據屬性名設置值的方法,這種方法就叫作KVC,Key-value coding。ide
下面摘錄一段李剛的《瘋狂iOS》,這段例子講的很清楚,因此摘錄在下面:svg
5.5.1 簡單的 KVC
最基本的 KVC 由 NSKeyValueCoding 協議提供支持,最基本的操做屬性的兩個方法以下。
setValue:屬性值 forKey:屬性名:爲指定屬性設置值。
valueForKey:屬性名:獲取指定屬性的值。
例如,以下程序定義了 FKUser 類的接口部分。
程序清單: codes/05/5.5/FKUser. H學習
#import <Foundation/ Foundation. H> @interface FKUser: NSobject //使用@property 定義 3 個 property @property (nonatomic, copy) NSString* name; @property (nonatomic, copy) NSString* pass; @property (nonatomic, copy) NSDate* birth; @end
上面程序定義了 FKUser 類使用@property 定義 3 個 property,接下來應該爲該類定義實現部分,實現部分使用@synthesize 爲這 3 個 property 合成 setter 和 getter 方法。類實現部分代碼很是簡單,故此處再也不給出。
下面使用 KVC 來設置 FKUser 對象的屬性,以及訪問 FKUser 對象的屬性。程序代碼以下:ui
程序清單: codes/05/5.5/FKUserTest.m #import "FKUser. H" int main (int argc,char★argv []) { @autoreleasepool { //建立 FKUser 對象 FKUser* user = [[FKUser alloc] init]; // 使用 KVC 方式爲 name 屬性設置屬性值 [user setValue: @「孫悟空」forKey: @"name"]; //使用 KVC 方式爲 pass 屬性設置屬性值 [user setValue: @"1455" forKey: @"pass"]; //使用 KVC 方式爲 birth 屬性設置屬性值 [user setValue: [[NSDate alloc] init] forKey: @"birth"]; //使用KVC 獲取 FKUser 對象的屬性 NSLog (@"user 的 name 爲:%@「,【user valueForKey: @"name"]); NSLog (@"user 的 pass 爲:%@「,【user valueForKey: @"pass"]); NSLog (@"user 的 birth 爲:%@」,【user valueForKey: @"birth"]);
上面程序中前 3 行粗體字代碼使用 KVC 方式爲屬性設置屬性值,後 3 行粗體字代碼使用 KVC 模式獲取指定屬性的值。
編譯、運行上面的程序,看到以下輸出:atom
user 的 name 爲:孫悟空 user 的 pass 爲:1455 user 的 birth 爲:2013-04-08 16:55:49 +0000
在 KVC 編程方式中,不管調用 setValue: forKey 方法,仍是調用 valueForKey:方法,都是經過 NSString 對象來指定被操做屬性的,其中 forKey:標籤用於傳入屬性名。
對於 setValue:屬性值 forKey@"name「;代碼,底層的執行機制以下。
(1) 程序優先考慮調用「setName:屬性值;」代碼經過 setter 方法完成設置。
(2) 若是該類沒有 setName:方法,KVC 機制會搜索該類名爲_ name 的成員變量,不管該成員變量是在類接口部分定義,仍是在類實現部分定義,也不管用哪一個訪問控制符修飾,這條 KVC 代碼底層實際上就是對 name 成員變量賦值。
(3) 若是該類既沒有 setName:方法,也沒有定義_ name 成員變量,KVC 機制會搜索該類名爲 name 的成員變量,不管該成員變量是在類接口部分定義,仍是在類實現部分定義,也不管用哪一個訪問控制符修飾,這條 KVC 代碼底層實際就是對 name 成員變量賦值。
(4) 若是上面 3 條都沒有找到,系統將會執行該對象的 setValue: forUndefinedKey:方法。
默認的 setValue: forUndefinedKey:方法實現就是引起一個異常,這個異常將會| 致使程序由於異常結束。
對於「valueforKey@「name」;,」代碼,底層的執行機制以下。
(1) 程序優先考慮調用「name;」代碼來獲取該 getter 方法的返回值。
(2) 若是該類沒有 name 方法,KVC 機制會搜索該類名爲_ name 的成員變量,不管該成員變量是在類接口部分定義,仍是在類實現部分定義,也不管用哪一個訪問控制符修飾,這條 KVC
代碼底層實際就是返回_ name 成員變量的值。
(3) 若是該類既沒有 name 方法,也沒有定義_ name 成員變量,KVC 機制會搜索該類名爲name 的成員變量,不管該成員變量是在類接口部分定義,仍是在類實現部分定義,也不管用哪一個訪問控制符修飾,這條 KVC 代碼底層實際就是返回 name 成員變量的值。
(4) 若是上面 3 條都沒有找到,系統將會執行該對象的 valueforUndefinedKey:方法。
KVC的內容有點多,一章總結不完,這篇文章基本都是摘錄了,由於李剛的文章寫得至關清楚,那就經過摘錄來加深印象。
https://developer.apple.com/documentation/foundation/object_runtime/nskeyvaluecoding?language=objc
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/index.html
https://www.objc.io/issues/7-foundation/key-value-coding-and-observing/