iOS 關(guān)于KVC的簡(jiǎn)單知識(shí)

KVC(key-value coding),鍵值編碼。指在iOS開發(fā)中,開發(fā)者可以通過(guò)屬性名直接訪問(wèn)屬性,給屬性賦值或者取值,而不需要顯式的調(diào)用setter和getter方法,這樣就可以在運(yùn)行時(shí)動(dòng)態(tài)的訪問(wèn)和修改對(duì)象的屬性。

KVC常用的四個(gè)方法

- (nullable id)valueForKey:(NSString *)key;                          //直接通過(guò)Key來(lái)取值
- (void)setValue:(nullable id)value forKey:(NSString *)key;          //通過(guò)Key來(lái)設(shè)值
- (nullable id)valueForKeyPath:(NSString *)keyPath;                  //通過(guò)KeyPath來(lái)取值
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;  //通過(guò)KeyPath來(lái)設(shè)值

valueForKey 和 setValue: forKey:的簡(jiǎn)單用法

我們都知道當(dāng)一個(gè)對(duì)象的屬性在聲明文件(.h)中聲明時(shí),是可以用點(diǎn)語(yǔ)法訪問(wèn)并賦值的,但是如果聲明在實(shí)現(xiàn)文件(.m)中,在外面用點(diǎn)語(yǔ)法是訪問(wèn)不到的,此時(shí)KVC就起到作用了

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Book : NSObject
@end
#import "Book.h"
@interface Book()
@property (strong, nonatomic) NSString *name;
@property (assign, nonatomic) CGFloat price;
@end
@implementation Book
@end

//在控制器中實(shí)現(xiàn)下面代碼
Book *book1 = [[Book alloc]init];
[book1 setValue:@"ios" forKey:@"name"];
[book1 setValue:@12 forKey:@"price"];
 NSString *name = [book1 valueForKey:@"name"];
 NSNumber *price = [book1 valueForKey:@"price"];
 NSLog(@"name = %@,price = %@",name,price.floatValue);

//打印結(jié)果如下
name = ios,price = 12.000000

這樣以后我們自定義一些控件的時(shí)候訪問(wèn)私有屬性就方便多了。 另外,我們還可以修改系統(tǒng)控件的內(nèi)部屬性,如我們自定義好一個(gè)tabbar,可以用下面的方式替換系統(tǒng)本來(lái)的UITabbar

 [self setValue:[[CustomTabbar alloc]init] forKey:@"tabBar"];

valueForKeypath 和 setValue:forKeypath: 的簡(jiǎn)單用法

當(dāng)一個(gè)對(duì)象成為另一個(gè)對(duì)象的屬性時(shí),使用KVC就方便的多

#import <Foundation/Foundation.h>

@class Address;
@interface People : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) Address *address;
@property (assign, nonatomic) NSInteger age;
@end

@interface Address : NSObject
@property (strong, nonatomic) NSString *contry;
@end

#import "People.h"
@interface People ()
@end
@implementation People
@end

@interface Address ()
@end
@implementation Address
@end

//在控制器中實(shí)現(xiàn)下面代碼
Address *address = [[Address alloc]init];
address.contry = @"China";
People *people = [[People alloc]init];
people.address = address;
NSString *country1 = people.address.contry;
NSString *country2 = [people valueForKeyPath:@"address.contry"];
NSLog(@"1 = %@   2 = %@",country1,country2);
 
[people setValue:@"中國(guó)" forKeyPath:@"address.contry"];
country1 = people.address.contry;
country2 = [people valueForKeyPath:@"address.contry"]; NSLog(@"1 = %@   2 = %@",country1,country2);

KVC對(duì)于keyPath是搜索機(jī)制第一步就是分離key,用小數(shù)點(diǎn).來(lái)分割key,然后再像普通key一樣按照順序搜索下去。

KVC 和 字典

常用的兩個(gè)方法

- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
Addresss *add = [[Addresss alloc]init];
add.country = @"China";
add.province = @"Hebei";
add.city = @"Qinhuangdao";
add.district = @"Yanghedao";
NSArray *keys = @[@"country",@"province",@"city",@"district"];
//把對(duì)應(yīng)key所有的屬性全部取出來(lái)
NSDictionary *dict = [add dictionaryWithValuesForKeys:keys];
NSLog(@"dict = %@",dict);
    
//字典轉(zhuǎn)模型
NSDictionary *modiDic = @{@"country":@"中國(guó)",@"province":@"河北省",@"city":@"秦皇島市",@"district":@"洋河道"};
[add setValuesForKeysWithDictionary:modiDic];
NSLog(@"%@%@%@%@",add.country,add.province,add.city,add.district);

KVC處理非對(duì)象和自定義對(duì)象 (這里就不舉例了?。。。?/h2>

不是每一個(gè)方法都返回對(duì)象,但是valueForKey:總是返回一個(gè)id對(duì)象,如果原本的變量類型是值類型或者結(jié)構(gòu)體,返回值會(huì)封裝成NSNumber或者NSValue對(duì)象。這兩個(gè)類會(huì)處理從數(shù)字,布爾值到指針和結(jié)構(gòu)體任何類型。然后開以者需要手動(dòng)轉(zhuǎn)換成原來(lái)的類型。盡管valueForKey:會(huì)自動(dòng)將值類型封裝成對(duì)象,但是setValue:forKey:卻不行。你必須手動(dòng)將值類型轉(zhuǎn)換成NSNumber或者NSValue類型,才能傳遞過(guò)去。

對(duì)于自定義對(duì)象,KVC也會(huì)正確地設(shè)值和取值。因?yàn)閭鬟f進(jìn)去和取出來(lái)的都是id類型,所以需要開發(fā)者自己擔(dān)保類型的正確性,運(yùn)行時(shí)Objective-C在發(fā)送消息的會(huì)檢查類型,如果錯(cuò)誤會(huì)直接拋出異常。

KVC自帶的運(yùn)算

①簡(jiǎn)單集合運(yùn)算符
@sum @avg @count @min @max 相信大家都知道這些運(yùn)算符的意思

②對(duì)象運(yùn)算符 返回值都是NSArray
@distinctUnionOfObjects //獲取去重后的元素
@unionOfObjects//獲取所有的元素

    Book *book1 = [[Book alloc]init];
    book1.name = @"ios";
    book1.price = 12;

    Book *book2 = [[Book alloc]init];
    book2.name = @"ios2";
    book2.price = 15;

    Book *book3 = [[Book alloc]init];
    book3.name = @"ios3";
    book3.price = 111;

    Book *book4 = [[Book alloc]init];
    book4.name = @"ios1";
    book4.price = 111;

    NSArray *arrBooks = @[book1,book2,book3,book4];
    NSNumber *sum = [arrBooks valueForKeyPath:@"@sum.price"];
    NSLog(@"sum = %f",sum.floatValue);
    NSNumber *avg = [arrBooks valueForKeyPath:@"@avg.price"];
    NSLog(@"avg = %f",avg.floatValue);
    NSNumber *count = [arrBooks valueForKeyPath:@"@count"];
    NSLog(@"count = %f",count.floatValue);
    NSNumber *min = [arrBooks valueForKeyPath:@"@min.price"];
    NSLog(@"min = %f",min.floatValue);
    NSNumber *max = [arrBooks valueForKeyPath:@"@max.price"];
    NSLog(@"max = %f",max.floatValue);
    
    NSLog(@"distinctUnionOfObjects");//獲取去重后的元素
    NSArray *arrDistinch = [arrBooks valueForKeyPath:@"@distinctUnionOfObjects.price"];
    NSLog(@"arrDis = %@",arrDistinch);
    NSLog(@"UnionOfObjects");//獲取所有元素
    NSArray *arrUnion = [arrBooks valueForKeyPath:@"@unionOfObjects.price"];
    NSLog(@"arrUnion = %@",arrUnion);

總結(jié):KVC常用的兩種用法就 對(duì)私有變量訪問(wèn)和賦值 和 字典轉(zhuǎn)模型。
對(duì)于KVC如果你有好的見解歡迎隨時(shí)指教!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容