KVC總結(jié)

簡(jiǎn)介

KVC: Key Value Coding (鍵值編碼)

作用:

  • 取值和賦值
  • 改變對(duì)象的私有成員變量的值(重要)
  • 獲取對(duì)象的私有成員變量的值(重要)
  • 簡(jiǎn)單的字典轉(zhuǎn)模型
  • 模型轉(zhuǎn)字典
  • 批量取值

取值和賦值

在控制器中,可以使用[person setValue:@"張三" forKey:@"name"];對(duì)人類的對(duì)象的name屬性進(jìn)行賦值
也可以使用[person setValue:@"阿黃" forKeyPath:@"dog.name"];對(duì)人類的對(duì)象的dog屬性的name屬性進(jìn)行賦值
需要注意的是forKeyPath包含了forKey的所有功能,能夠根據(jù)點(diǎn)語(yǔ)法層層進(jìn)入取值

改變對(duì)象的私有成員變量的值(重要)

如果HSPerson類有一個(gè)私有成員變量_money,也可以在控制器中改變這個(gè)屬性的值[person setValue:@"199.99" forKeyPath:@"money"];
例如:

  • 改變分頁(yè)控制器的圖片
    [self.pageControl setValue:[UIImage imageNamed:@"current"]
  • CATransform3D中
//可以通過(guò)KVC的方式進(jìn)行設(shè)置屬性.
//但是CATransform3DMakeRotation它的值,是一個(gè)結(jié)構(gòu)體, 所以要把結(jié)構(gòu)轉(zhuǎn)成對(duì)象.
NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
[_imageView.layer setValue:value forKeyPath:@"transform.scale"];
  • 二維碼中設(shè)置濾鏡效果
  // 創(chuàng)建一個(gè)二維碼濾鏡
let filter = CIFilter(name: "CIQRCodeGenerator")     
//  恢復(fù)默認(rèn)設(shè)置
 filter?.setDefaults(
// 輸入的內(nèi)容必須是NSData
let inputStr = contentStr
let data = inputStr.dataUsingEncoding(NSUTF8StringEncoding)
filter?.setValue(data, forKey: "inputMessage")  
// 設(shè)置濾鏡的糾錯(cuò)率
 filter?.setValue("M", forKey: "inputCorrectionLevel")

獲取對(duì)象的私有成員變量的值(重要)

NSLog(@"%f", [[person valueForKeyPath:@"_money"] floatValue]);
例如

  • 改變UITextField占位文字顏色
UILabel *placeholderLabel = [self valueForKey:@"placeholderLabel"];
placeholderLabel.textColor = placeholderColor;

簡(jiǎn)單的字典轉(zhuǎn)模型

在構(gòu)造方法中使用[self setValuesForKeysWithDictionary:dict];代碼

//HSPerson中聲明了一個(gè)HSBook模型的數(shù)組,HSBook模型中包含name和price屬性
//HSPerson.m中
-(NSString *)description{
    return [NSString stringWithFormat:@"姓名:%@----身高:%f", _name, _height];
}

- (instancetype)initWithDict:(NSDictionary *)dict{
    if (self = [super init]) {
        /*
        self.name = dict[@"name"];
        self.height = [dict[@"height"] floatValue];
         */
        // KVC
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}

+ (instancetype)personWithDict:(NSDictionary *)dict{
    return [[self alloc] initWithDict:dict];
}
//控制器
NSDictionary *dict = @{
                           @"name": @"張三",
                           @"height" : @18,
                           @"books" :@[
                                   @{@"name": @"葵花寶典", @"price": @1.009},
                                   @{@"name": @"辟邪劍譜", @"price": @111111.009}
                                   ]
                           };
    HSPerson *person = [[HSPerson alloc] initWithDict:dict];
    
    NSLog(@"%@-----%@", person, person.books);

需要注意的是利用KVC轉(zhuǎn)模型只能轉(zhuǎn)一層,所以轉(zhuǎn)出的模型結(jié)果為

2016-05-19 17:53:20.898 KVCTest[3998:166887] 姓名:張三----身高:18.000000-----(
        {
        name = "\U8475\U82b1\U5b9d\U5178";
        price = "1.009";
    },
        {
        name = "\U8f9f\U90aa\U5251\U8c31";
        price = "111111.009";
    }
)

可見(jiàn)KVC實(shí)現(xiàn)不了多層的數(shù)據(jù)轉(zhuǎn)模型

  • 底層實(shí)現(xiàn)

    • 1.先去看有沒(méi)有跟key值相同的成員屬性,如果有,就會(huì)調(diào)用該成員屬性的set方法,給該成員屬性賦值.
    • 2.如果沒(méi)有跟它相同的成員屬性的set方法, 會(huì)直接給該屬性賦值.
    • 3.還會(huì)去判斷有沒(méi)有跟它相同名稱,并且?guī)в邢聞澗€的成員屬性.如果有,就給該屬性賦值.
    • 4.如果沒(méi)有帶有下劃線的成員屬性,就會(huì)直接報(bào)錯(cuò).
  • KVC字典轉(zhuǎn)模型弊端:必須保證鲜结,模型中的屬性和字典中的key一一對(duì)應(yīng)识颊。

    • 如果不一致检柬,就會(huì)調(diào)用[<Status 0x7fa74b545d60> setValue:forUndefinedKey:]
      報(bào)key找不到的錯(cuò)峡竣。
    • 分析:模型中的屬性和字典的key不一一對(duì)應(yīng)病线,系統(tǒng)就會(huì)調(diào)用setValue:forUndefinedKey:報(bào)錯(cuò)。
    • 解決:重寫對(duì)象的setValue:forUndefinedKey:,把系統(tǒng)的方法覆蓋同波,就能繼續(xù)使用KVC空骚,字典轉(zhuǎn)模型了。

模型轉(zhuǎn)字典

在構(gòu)造方法中調(diào)用[person dictionaryWithValuesForKeys:@[@"name", @"height", @"books"]];

HSPerson *person = [[HSPerson alloc] init];
person.name = @"張三";
person.height = 1.78;
HSBook *b1 = [[HSBook alloc] init];
b1.name = @"tianlongbabu";
b1.price = 50.0;
    
HSBook *b2 = [[HSBook alloc] init];
b2.name = @"shediaoyinxing";
b2.price = 50.0;
    
person.books = @[b1,b2];
    
NSDictionary *dict = [person dictionaryWithValuesForKeys:@[@"name", @"height", @"books"]];
NSLog(@"%@", [dict class]);
NSLog(@"%@", dict);
2016-05-19 19:14:14.999 KVCTest[4358:217403] __NSDictionaryI
2016-05-19 19:14:15.000 KVCTest[4358:217403] {
    books =     (
        "<HSBook: 0x7fd6b9c1e2c0>",
        "<HSBook: 0x7fd6b9c21a50>"
    );
    height = "1.78";
    name = "\U5f20\U4e09";
}

批量取值

如果想取出books數(shù)組中所有的書的name,可以使用如下代碼
NSArray *names = [person valueForKeyPath:@"books.name"]; 或者
NSArray *names = [person.books valueForKeyPath:@"name"];

//結(jié)果
2016-05-19 19:15:47.576 KVCTest[4367:218579] (
    tianlongbabu,
    shediaoyinxing
)

也可以計(jì)算數(shù)組的長(zhǎng)度和里面屬性的和
NSLog(@"%@",[person valueForKeyPath:@"books.@count"]);
NSLog(@"%@",[person valueForKeyPath:@"books.@sum.price"]);

//結(jié)果
2016-05-19 19:20:29.658 KVCTest[4386:222221] 2
2016-05-19 19:20:29.675 KVCTest[4386:222221] 100
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末驶忌,一起剝皮案震驚了整個(gè)濱河市矛辕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌付魔,老刑警劉巖聊品,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抒抬,居然都是意外死亡杨刨,警方通過(guò)查閱死者的電腦和手機(jī)晤柄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門擦剑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芥颈,你說(shuō)我怎么就攤上這事惠勒。” “怎么了爬坑?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵纠屋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我盾计,道長(zhǎng)售担,這世上最難降的妖魔是什么赁遗? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮族铆,結(jié)果婚禮上岩四,老公的妹妹穿的比我還像新娘。我一直安慰自己哥攘,他們只是感情好剖煌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逝淹,像睡著了一般耕姊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上栅葡,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天茉兰,我揣著相機(jī)與錄音,去河邊找鬼欣簇。 笑死邦邦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的醉蚁。 我是一名探鬼主播燃辖,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼网棍!你這毒婦竟也來(lái)了黔龟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤滥玷,失蹤者是張志新(化名)和其女友劉穎氏身,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惑畴,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛋欣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了如贷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陷虎。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杠袱,靈堂內(nèi)的尸體忽然破棺而出尚猿,到底是詐尸還是另有隱情,我是刑警寧澤楣富,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布凿掂,位于F島的核電站,受9級(jí)特大地震影響纹蝴,放射性物質(zhì)發(fā)生泄漏庄萎。R本人自食惡果不足惜踪少,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望糠涛。 院中可真熱鬧秉馏,春花似錦、人聲如沸脱羡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锉罐。三九已至帆竹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脓规,已是汗流浹背栽连。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侨舆,地道東北人秒紧。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挨下,于是被迫代替她去往敵國(guó)和親熔恢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 概述由于ObjC主要基于Smalltalk進(jìn)行設(shè)計(jì)臭笆,因此它有很多類似于Ruby叙淌、Python的動(dòng)態(tài)特性,例如動(dòng)態(tài)類...
    汪飛蛟閱讀 217評(píng)論 0 0
  • KVC(Key-Value Coding) KVC最常見(jiàn)的兩個(gè)用途: 給私有的成員變量賦值(當(dāng)然公有的也可以)比如...
    ForeverYoung21閱讀 1,164評(píng)論 1 15
  • 1.給私有的成員變量賦值(當(dāng)然公有的也可以) 比如一個(gè)類有一個(gè)私有成員變量(在.m文件中)愁铺,用KVC的方式然后可以...
    sunny12閱讀 405評(píng)論 0 1
  • OC最實(shí)用的runtime總結(jié)督勺,面試、工作你看我就足夠了在验! 前言runtime的資料網(wǎng)上有很多了玷氏,部分有些晦澀難懂...
    small_Sun閱讀 926評(píng)論 1 12
  • 襲人比伶俐做女紅不如晴雯,與人講理吵架不如麝月腋舌,模樣也是“次一等”,可她卻成了寶玉身邊最親近的人渗蟹,怡紅院的首席大丫...
    姑射閱讀 452評(píng)論 0 3