鍵值編碼(Key Value Coding,KVC):使開發者沒必要進行任何操做就能夠進行屬性的動態讀寫。html
KVC操做方法由 NSKeyValueCoding 協議提供,而 NSObject 實現了這個協議,所以 ObjC 中幾乎全部的對象都支持KVC操做,經常使用的操做方法以下:ios
1)動態設置: setValue:forKey: 用於簡單路徑, setValue:forKeyPath: 用於複合路徑。如 Person 類有一個 Account 類型的屬性,那麼 Person.Account 就是一個複合屬性。數組
2)動態讀取: valueForKey: 、 valueForKeyPath: 。函數
補充:鍵值觀察(Key Value Observer,KVO):監聽某一個模型的屬性,只要該模型屬性的值發生變化就通知你。編碼
新建 Command Line Tool 項目,並命名爲 KVCDemo 。緊接着,爲項目添加一個繼承自 NSObject 類的 Person 類,爲該新類添加名字和年齡屬性,以下:atom
1 //Person.h 2 @property (nonatomic, copy) NSString *name; 3 @property (nonatomic, assign) int age;
在 Person 類的實現文件中重寫 description 方法:spa
1 //Person.m 2 - (NSString *)description { 3 return [NSString stringWithFormat:@"<%@:%p>, {name:%@, age:%d}.", [self class], self, self.name, self.age]; 4 }
上述中 %p 指代指針。指針
在 main.m 文件中對 Person 進行簡單的處理:code
1 //main.m 2 int main(int argc, const char * argv[]) { 3 @autoreleasepool { 4 Person *p1 = [[Person alloc] init]; 5 [p1 setValue:@"WJQ" forKey:@"name"]; 6 [p1 setValue:@"23" forKey:@"age"]; 7 8 Person *p2 = [[Person alloc] init]; 9 [p2 setValue:@"LWX" forKey:@"name"]; 10 [p2 setValue:@"22" forKey:@"age"]; 11 NSLog(@"%@. %@.", p1, [p2 valueForKey:@"name"]); 12 } 13 return 0; 14 }
使用 setValue:forKey: 進行KVC操做時,系統會自動判斷對象屬性的類型並完成轉換,如上例將 @"23" 轉換爲 23 。orm
輸出爲:
<Person:0x1006001c0>, {name:WJQ, age:23}.. LWX.
如何生成只包含 name 屬性的數組,並打印出來?
在 main.m 文件中中導入 Person 類的頭文件,並修改 main 函數的代碼:
1 int main(int argc, const char * argv[]) { 2 @autoreleasepool { 3 Person *p1 = [[Person alloc] init]; 4 [p1 setValue:@"WJQ" forKey:@"name"]; 5 [p1 setValue:@"23" forKey:@"age"]; 6 7 Person *p2 = [[Person alloc] init]; 8 [p2 setValue:@"LWX" forKey:@"name"]; 9 [p2 setValue:@"22" forKey:@"age"]; 10 11 NSArray *persons = @[p1, p2]; //建立Person對象的數組 12 NSLog(@"%@", persons); 13 NSMutableArray *arrayM = [NSMutableArray array]; //用於存放各個Person的name 14 for (Person *p in persons) { 15 [arrayM addObject:[p valueForKeyPath:@"name"]]; 16 } 17 NSLog(@"%@", arrayM); 18 } 19 return 0; 20 }
輸出爲:
( "<Person:0x100208dc0>, {name:WJQ, age:23}.", "<Person:0x100209c80>, {name:LWX, age:22}." ) ( WJQ, LWX )
因爲使用KVC按鍵值路徑取值時,若是對象不包含指定的鍵值,會自動進入對象內部,查找對象的屬性。在不改變輸出的狀況下,修改上述代碼爲:
1 int main(int argc, const char * argv[]) { 2 @autoreleasepool { 3 Person *p1 = [[Person alloc] init]; 4 [p1 setValue:@"WJQ" forKey:@"name"]; 5 [p1 setValue:@"23" forKey:@"age"]; 6 7 Person *p2 = [[Person alloc] init]; 8 [p2 setValue:@"LWX" forKey:@"name"]; 9 [p2 setValue:@"22" forKey:@"age"]; 10 11 NSArray *persons = @[p1, p2]; //建立Person對象的數組 12 NSLog(@"%@", persons); 13 NSMutableArray *arrayM = [NSMutableArray array]; //用於存放各個Person的name 14 [arrayM addObject:[persons valueForKeyPath:@"name"]]; 15 NSLog(@"%@", arrayM); 16 } 17 return 0; 18 }
演示根據鍵值路徑取值,KVC機制會自動層層深刻,並獲取對應的鍵值。
爲項目新建一個 Book 類繼承自 NSObject ,添加 bookName 屬性:
1 //Book.h 2 @property(nonatomic, copy) NSString *bookName;
修改 Book 類的 description 方法:
1 //Book.m 2 - (NSString *)description { 3 return [NSString stringWithFormat:@"<%@, %p>, {bookName:%@}", [self class], self, self.bookName]; 4 }
接着在 Person 類的頭文件中導入 Book.h ,再添加一個 Book 類的對象屬性,以下:
1 //Person.h 2 @property (nonatomic, strong) Book *book;
修改 Person 類的 description 方法,使其輸出 book 屬性:
1 //Person.m 2 - (NSString *)description { 3 return [NSString stringWithFormat:@"<%@:%p>, {name:%@, age:%d, book:%@}.", [self class], self, self.name, self.age, self.book]; 4 }
最後,修改 main 函數:
1 //main.m 2 int main(int argc, const char * argv[]) { 3 @autoreleasepool { 4 Person *p1 = [[Person alloc] init]; 5 [p1 setValue:@"WJQ" forKey:@"name"]; 6 [p1 setValue:@"23" forKey:@"age"]; 7 Book *b1 = [[Book alloc] init]; 8 b1.bookName = @"iPhone"; 9 p1.book = b1; 10 11 Person *p2 = [[Person alloc] init]; 12 [p2 setValue:@"LWX" forKey:@"name"]; 13 [p2 setValue:@"22" forKey:@"age"]; 14 Book *b2 = [[Book alloc] init]; 15 b2.bookName = @"iOS"; 16 p2.book = b2; 17 18 NSArray *persons = @[p1, p2]; //建立Person對象的數組 19 NSLog(@"%@", persons); 20 NSArray *arrayM = [persons valueForKeyPath:@"book.bookName"]; 21 NSLog(@"%@", arrayM); 22 } 23 return 0; 24 }
輸出爲:
( "<Person:0x1002095d0>, {name:WJQ, age:23, book:<Book, 0x10020c4c0>, {bookName:iPhone}}.", "<Person:0x10020c520>, {name:LWX, age:22, book:<Book, 0x10020c540>, {bookName:iOS}}." ) ( iPhone, iOS )
參考博客:ios開發UI篇—Kvc簡單介紹