你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> 鍵值編碼和通用編程

鍵值編碼和通用編程

編輯:關於IOS

鍵值編碼(KVC)是Cocoa一個通用的用於獲取和設定值的一個協議。在編程中,“通用”這詞是用於描述一種可以適用於不同情境的實現方式。通用代碼可以減少項目中代碼總量並使得軟件可以處理程序員無法預知的情景。Cocoa至始至終都很重視通用、可復用代碼。
比如,設定一個對象first name和lastname的一種不通用的方式如下:
[person setFirstName: @"Scott"];
[person setLastName:  @"Stevenson"];

這挺好的,不過通過使用KVC消息可以寫更通用的代碼:
[person setValue:@"Scott" forKey:@"firstName"];
[person setValue:@"Stevenson" forKey:@"lastName"];

新手們可能會質疑這個的意義。實際上,KVC版看起來需要更多代碼輸入。讓就讓我選擇一個更能體現KVC價值的場景。
首先,我們定義一個類:
@interface CDCPerson : NSObject
{
NSString * firstName;
NSString * lastName;
NSNumber * phoneNumber;
NSString * emailAddress;
}
- (void) setFirstName:    (NSString *)value;
- (void) setLastName:     (NSString *)value;
- (void) setPhoneNumber:  (NSNumber *)value;
- (void) setEmailAddress: (NSString *)value;
@end

一些實際使用代碼如下:

// 假設inputValues包含我們想設定到person上的鍵值
NSDictionary *inputValues;
CDCPerson    *person = [[CDCPerson alloc] init];
NSEnumerator *e = [inputValues keyEnumerator];
id dictKey, dictValue;
while ( dictKey = [e nextObject] )
{
dictValue = [inputValues valueForKey: dictKey];
[person setValue: dictValue forKey: dictKey];
}

該代碼段是通用的,意味著我們不需要在每次Person類添加新的實例變量的時候改變代碼。
但是還可以更好!如下就是一個上述代碼的簡化版本:
// 假設inputValues包含我們想設定到person上的鍵值
NSDictionary *inputValues;
CDCPerson    *person = [[CDCPerson alloc] init];
[person setValuesForKeysWithDictionary: inputValues];

很隱晦吧?如下是Apple關於-setValuesForKeysWithDictionary:實現機制的解釋:
通過鍵值對設定消息接收方的屬性值,鍵用於識別各個屬性。默認實現是對每個鍵值對調用setValue:forKey:,在鍵值對有NSNull值的情況下替換成nil。
換句話說,這和第一個例子沒有什麼區別。但是-setValue:forKey:到底做了些什麼呢?這就是KVC的魔力所在。它實際上會找到-setFirstName:、-setLastName:、setPhoneNumber: 以及-setEmailAddress: 的實現並調用它們。如果無法找到這些,KVC會嘗試幾種可能直至最終將值設定到實例變量上。
KVC也可以用來從一個對象中獲取值:

// 假設person已經存在並被賦值
CDCPerson *person;
NSMutableDictionary *outputValues;
outputValues = [NSMutableDictionary dictionary];
NSArray *keys;
keys = [NSArray arrayWithObjects: @"firstName",
@"lastName",
@"phoneNumber",
@"emailAddress",
nil];
NSEnumerator *e = [keys objectEnumator];
id key, value;
while ( key = [e nextObject] )
{
value = [person valueForKey: key];
[outputValues setValue: value forKey: key];
}

或者更簡單的版本:
// 假設person已經存在並被賦值
CDCPerson    *person;
NSArray      *keys;
keys = [NSArray arrayWithObjects: @"firstName",
@"lastName",
@"phoneNumber",
@"emailAddress",
nil];
NSDictionary *outputValues;
outputValues = [person dictionaryWithValuesForKeys: keys];

和設定值一樣,通過-valueForKey:獲取值讓KVC去查找和鍵值有相同名字的方法:

// 這回讓KVC查找一個名為-firstName的方法
NSString *name = [person valueForKey:@"firstName"];

鍵值編碼是Cocoa Bindings和Core Data的關鍵,所以了解一些基礎知識是很值得的。KVC可以處理如下一些鍵值路徑:
// 獲取
[obj valueForKeyPath: @"storage.firstName"];
// 設定
[obj setValue: @"Scott" forKeyPath: @"storage.firstName"];

作用同如下代碼:
// getting
[[obj storage] firstName];
// setting
[[obj storage] setFirstName:@"Scott"];

鍵值編碼更多信息可以參照Apple開發者論壇上的該頁。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved