iOS開發基礎-KVC簡單介紹

1、KVC介紹

  鍵值編碼(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):監聽某一個模型的屬性,只要該模型屬性的值發生變化就通知你。編碼

 

2、代碼實例1

  新建 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.

 

3、代碼實例2

  如何生成只包含 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 }

 

3、代碼實例3

  演示根據鍵值路徑取值,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簡單介紹

實例代碼:http://pan.baidu.com/s/1dDYZAOL

相關文章
相關標籤/搜索