RAC學習筆記之一:KVC(一)

RAC學習筆記之一:KVC(一)html

原帖收藏於IT老兵博客ios

前言

學習RAC,須要先去了解KVC和KVO,這裏對KVC進行一下總結。web

正文

KVC

參考蘋果官網的介紹編程

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/

相關文章
相關標籤/搜索