聊聊 KVO 與 KVC 吧

先聊聊 KVO 與 KVC 的區(qū)別吧:
KVO是指鍵-值-觀察者模式, 鍵值監(jiān)聽, 監(jiān)聽一個對象屬性值的改變池摧。KVO是基于KVC的荔泳。
KVC 是指鍵-值編碼, 通過一個字符串的 key 來找到value , 是 value for key 方法, 直接或通過實例變量訪問的機(jī)制 橙数。利用 KVC 可以隨意修改一個對象的屬性或者成員變量, 并且私有變量也可修改尊流。

一. KVO

KVO是指鍵-值-觀察者(key-value-observe),
是一種使對象獲取其他對象的特定屬性變化的通知機(jī)制。
與NSNotification 不同的是灯帮。KVO 不需要通知中心對象崖技。而是在對象屬性變化之后會直接通知觀察者逻住。

KVO的步驟:

**1. 注冊觀察者 **
為了正確接收屬性的變化通知,觀察者對象必須先發(fā)一個消息給被觀察者對象

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;

/*
NSKeyValueObservingOptions 可選的是一個枚舉值迎献。我們通常用到的是兩個
NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew
當(dāng)屬性發(fā)生變化時瞎访。我們可以把舊值和新值傳遞給觀察者 
*/

**2.接收變化通知 **
應(yīng)該注意的是如果只是使用成員變量改變值的話是不會觸發(fā)KVO的。要使用點語法忿晕,或者是KVC的方式改變值

// object 是被監(jiān)聽對象
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSString *,id> *)change
                       context:(void *)context;

**3.移除觀察者身份 **
在不需要觀察時要進(jìn)行移除

- (void)removeObserver:(NSObject *)observer
            forKeyPath:(NSString *)keyPath;

二.KVC

什么是KVC
KVC是指key-value-code装诡,鍵-值編碼,是一種用于間接訪問對象屬性的機(jī)制践盼。使用KVC可以直接修改對象屬性鸦采,即使是私有的也可以訪問。 如果是基本數(shù)據(jù)類型的應(yīng)該封裝一下咕幻。

KVC的基本使用有下面幾點:
鍵值訪問
路徑訪問
取數(shù)組內(nèi)的數(shù)據(jù)
一些簡單的運(yùn)算
下面按照這幾點用法來介紹一下

// 為了方便以后操作渔伯,我們先簡單定義一下幾個類

// Person類
#import <Foundation/Foundation.h>
#import "Totoro.h"

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSUInteger age;
@property (nonatomic, strong) Totoro *Totoro;
@property (nonatomic, strong) NSArray *Totoros;

@end

// Totoro類
#import <Foundation/Foundation.h>

@interface Totoro : NSObject

@property (nonatomic, assign) NSUInteger weight;

@end

// 為了證明上面說的可以修改私有屬性,我們?yōu)?Totoro 添加一個私有的屬性
#import "Totoro.h"

@interface Totoro ()

@property (nonatomic, copy) NSString *name;

@end

@implementation Totoro

@end

基本設(shè)置完了之后肄程,我們可以在Main函數(shù)里面進(jìn)行一下操作

// 先創(chuàng)建一個人對象
Person *me = [[Person alloc] init];
Totoro *Totoro = [[Totoro alloc] init];
me.Totoro = Totoro; // 我養(yǎng)了一只龍貓

按照我們最為傳統(tǒng)的賦值方法我們要給人賦值一個name的話 我們通常會使用點語法進(jìn)行賦值

// 本質(zhì)上是調(diào)用了 [me setName:@"smile麗"];
me.name = @"smile麗"; // 這里相當(dāng)于調(diào)用了setter方法

// 本質(zhì)上是調(diào)用了 NSLog(@"%@", [me name]);
NSLog(@"%@", me.name); // 這里相當(dāng)于調(diào)用getter方法

1> 鍵值訪問

那我們來看一下 使用KVC的方式應(yīng)該如何去賦值.使用KVC锣吼, 會自動尋找成員變量(xxx),如果找不到蓝厌,然后再去掉去尋找玄叠,如果再找不到,就會報錯拓提。而不是去調(diào)用setter 和 getter 方法

// @() 對基本數(shù)據(jù)類型封裝成對象
 [me setValue:@(24) forKey:@"age"];
 NSLog(@"%@", [me valueForKey:@"age"]);

2> 路徑訪問

什么是路徑訪問读恃,對于一個類來說,可能他的屬性是其他的類代态,如果要修改這里的屬性寺惫。我們需要先通過路徑來尋找到該屬性,然后再進(jìn)行賦值.

[me setValue:@"大白" forKeyPath:@"totoro.name"]; // 注意這里的(.)只是路徑不是點語法
NSLog(@"%@", [me valueForKeyPath:@"totoro.name"]);

3> 取數(shù)組的數(shù)據(jù)

對于如果我們的數(shù)組里面存放的是對象蹦疑,如果我們要獲取數(shù)組里面每個對象的屬性西雀。這樣的話,最容易的方法就是遍歷數(shù)組歉摧。然后取出每個屬性進(jìn)行添加到數(shù)組中艇肴。這時候我們也可以使用KVC快速解決這種問題.
為了測試,我給Person一個totoros的數(shù)組屬性叁温,下面造一下數(shù)據(jù).

NSMutableArray *totoros = [NSMutableArray array];
for (int i = 0; i < 4; i++) {
    Totoro *totoro = [[totoro alloc] init];
    NSString *name = [NSString stringWithFormat:@"大白_%d", i];
    [totoro setValue:name forKey:@"name"];
    NSUInteger weight = 3.8 + i;
    [totoro setValue:@(weight) forKey:@"weight"]; // 這個數(shù)據(jù)在第四點用到
    [totoros addObject:totoro];
}

我們?nèi)绾螌崿F(xiàn)上述的需求呢

使用 KVC回去屬性的數(shù)組

NSMutableArray *array = [totoros mutableArrayValueForKeyPath:@"name"];
NSLog(@"%@", array);
/*
 (
 "大白_0",
 "大白_1",
 "大白_2",
 "大白_3"
 )
*/

4> 一些簡單的運(yùn)算
可以使用的關(guān)鍵字: 數(shù)量@count, 最大值@max, 最小值@min, 和@sum

me.totoros = totoros;
// 取到所有的相關(guān)屬性元素,進(jìn)行計算, 由于方法返回的是 id, 所以要使用對象接收,我們可以使用 NSNumber, 而不是 int 之類的
NSLog(@"數(shù)量:%@", [p valueForKeyPath:@"totoros.@count"]);
NSLog(@"平均體重%@", [p valueForKeyPath:@"totoros.@avg.weight"]);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豆挽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子券盅,更是在濱河造成了極大的恐慌帮哈,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锰镀,死亡現(xiàn)場離奇詭異娘侍,居然都是意外死亡咖刃,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門憾筏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嚎杨,“玉大人,你說我怎么就攤上這事氧腰》阏悖” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵古拴,是天一觀的道長箩帚。 經(jīng)常有香客問我,道長黄痪,這世上最難降的妖魔是什么紧帕? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮桅打,結(jié)果婚禮上是嗜,老公的妹妹穿的比我還像新娘。我一直安慰自己挺尾,他們只是感情好鹅搪,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著遭铺,像睡著了一般丽柿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上掂僵,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天航厚,我揣著相機(jī)與錄音顷歌,去河邊找鬼锰蓬。 笑死,一個胖子當(dāng)著我的面吹牛眯漩,可吹牛的內(nèi)容都是我干的芹扭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼赦抖,長吁一口氣:“原來是場噩夢啊……” “哼舱卡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起队萤,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤轮锥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后要尔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舍杜,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡新娜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了既绩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片概龄。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖饲握,靈堂內(nèi)的尸體忽然破棺而出私杜,到底是詐尸還是另有隱情,我是刑警寧澤救欧,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布衰粹,位于F島的核電站,受9級特大地震影響颜矿,放射性物質(zhì)發(fā)生泄漏寄猩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一骑疆、第九天 我趴在偏房一處隱蔽的房頂上張望田篇。 院中可真熱鬧,春花似錦箍铭、人聲如沸泊柬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兽赁。三九已至,卻和暖如春冷守,著一層夾襖步出監(jiān)牢的瞬間刀崖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工拍摇, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留亮钦,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓充活,卻偏偏與公主長得像蜂莉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子混卵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

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

  • 在編程中映穗,最常見的就是程序的流程取決于你所使用的各種變量和屬性的值,根據(jù)變量和屬性的值確定后面運(yùn)行的代碼幕随,有時會檢...
    pro648閱讀 1,634評論 2 27
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,130評論 30 470
  • 最近發(fā)現(xiàn)之前看的東西沒一會就忘記了蚁滋,所以寫來好一些,也建議大家吧學(xué)到了記錄下來這樣加深印象,也可以幫助到別人辕录。首先...
    _技術(shù)支持閱讀 922評論 1 1
  • KVC/KVO 概念 KVC : 即 Key-Value-Coding澄阳,用于鍵值編碼。作為 cocoa 的一個標(biāo)準(zhǔn)...
    滿臉胡茬的小碼農(nóng)閱讀 1,950評論 2 8
  • 1.KVC 關(guān)于 KVC 和 KVO ,我之前的總結(jié)文章有寫過,但是趨于表面速梗,沒有探究其內(nèi)部真正的實現(xiàn)原理和進(jìn)階用...
    Liberalism閱讀 1,076評論 0 5