天天看點

IOS-Foundation-KVC

本人錄制技術視訊位址:https://edu.csdn.net/lecturer/1899 歡迎觀看。

1. 基本概念

KVC,即是指 Key-Value-Coding,一個非正式的 Protocol,提供一種機制來間接通路對象的屬性。

為了說明其使用場合,首先建立一個Person類,然後分以下幾點進行說明。

@class  Card;
@interface Person : NSObject

@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign) int age;
/* 引用了其他一個對象 */
@property (nonatomic,strong) Card *card;

@end
           

2. 使用場合

Situation One: 方法的形式參數是id類型

void setPerson(id person) {

    [person setValue:@"Jason" forKey:@"name"];
    [person setValue:@10 forKey:@"age"];
    
    NSString *name = [person valueForKey:@"name"];
    NSNumber *ageNumber = [person valueForKey:@"age"];
    NSLog(@"Name:%@,Age:%@",name,[ageNumber stringValue]);
}
           

下面的代碼為方法調用

Person *p = [[Person alloc] init];
setPerson(p);
           

因為形參是id,是以肯定不可以使用點文法。這裡就可以使用KVC進行對象屬性的指派取值工作。

Situation Two: valueForKey & valueForKeyPath

Person *p = [[Person alloc] init];
p.name = @"Jason";
    
NSString *name = [p valueForKey:@"name"];
NSLog(@"Name:%@",name);
    
p.card = [[Card alloc] init];
p.card.no = @"No.1";
NSString *cardId = [p valueForKeyPath:@"card.no"];
NSLog(@"Card Id:%@",cardId);
           

valueForKey 可以直接取得對象屬性的值;如果對象中的屬性是其他對象,就可以使用valueForKeyPath通路屬性對象中得某個屬性值,如上例中的cord.no

Situation Three: For Array

Person *p = [[Person alloc] init];
p.name = @"Rose";
    
Person *p2 = [[Person alloc] init];
p2.name = @"Jack";
    
Person *p3 = [[Person alloc] init];
p3.name = @"Dog";
    
NSArray *ps = @[p,p2,p3];
    
NSArray *names = [ps valueForKey:@"name"];
    
[ps setValue:@"Tom" forKey:@"name"];
    
NSLog(@"names:%@",names);
           

通過KVC快速得到對象數組中某個屬性的值的集合

NSArray *names = [ps valueForKey:@"name"];

通過KVC快速重置數組中所有對象的某個屬性值

[ps setValue:@"Tom" forKey:@"name"];

實際應用場景舉例:

預設的導航控制器上面的leftBarButtonItem和rightBarButtonItem的位置是不能調節位置的,這時我們可以通過KVC自定義UINavigationBar,然後實作自己想要的效果,大緻代碼如下

[self setValue:[[LFNavigationBar alloc] init] forKey:@"navigationBar"];
           

這裡的navigationBar是 UINavigationController 的隻讀屬性,

@property(nonatomic,readonly) UINavigationBar *navigationBar;
           

是無法進行指派操作的,但我們可以通過KVC進行修改操作。

3.   補充說明

setObject: forKey: 與  setValue: forKey:

NSMutableDictionary *dict = nil;
// 字典指派隻能用setObject
[dict setObject:@"Object" forKey:@"key"];
// 字典不能這樣使用,是給KVC使用的
[dict setValue:@"Value" forKey:@"Key"];
           

繼續閱讀