KVC總結(jié)

簡介

KVC: Key Value Coding (鍵值編碼)

作用:

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

取值和賦值

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

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

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

  • 改變分頁控制器的圖片
    [self.pageControl setValue:[UIImage imageNamed:@"current"]
  • CATransform3D中
//可以通過KVC的方式進(jìn)行設(shè)置屬性.
//但是CATransform3DMakeRotation它的值,是一個結(jié)構(gòu)體, 所以要把結(jié)構(gòu)轉(zhuǎn)成對象.
NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
[_imageView.layer setValue:value forKeyPath:@"transform.scale"];
  • 二維碼中設(shè)置濾鏡效果
  // 創(chuàng)建一個二維碼濾鏡
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è)置濾鏡的糾錯率
 filter?.setValue("M", forKey: "inputCorrectionLevel")

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

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

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

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

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

//HSPerson中聲明了一個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";
    }
)

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

  • 底層實現(xiàn)

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

    • 如果不一致,就會調(diào)用[<Status 0x7fa74b545d60> setValue:forUndefinedKey:]
      key找不到的錯。
    • 分析:模型中的屬性和字典的key不一一對應(yīng),系統(tǒng)就會調(diào)用setValue:forUndefinedKey:報錯。
    • 解決:重寫對象的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
)

也可以計算數(shù)組的長度和里面屬性的和
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)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,991評論 2 374

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

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