IOS KVC,KVO

KVC

KVC是key Value Coding的縮寫,主要方法有setValue:forKey和valueForKey:。

setValue:forKey:主要是賦值。value參數是值,key參數是變量名。

eg:[student setValue:@”張3”forKey:@”name”];

給student的name屬性賦值為張3 。

valueForKey: 主要是取值。key是變量名,方法返回變量的值。

setValue:forKeyPath:可以通過“.”的方式,給私有的自定義類型的私有變量賦值。

eg:[student setValue:@”LI4” forKeyPath:@”person.name”];

利用KVC機制,可以給繼承于NSObject類的私有變量賦值。

注意:

key里面的屬性,是什么類型,value對應的就應該是什么類型。

key里面的屬性,一定要是類的屬性,否則會報錯。

主要用在多個類,對象嵌套的時候。

譬如:

我們有一個人 這個人有一個手機類 這個手機類 有一個電池類 我們要獲取這個電池類 比之前復雜了吧。

沒有KVC

Persion *persion =[ [Persion alloc] init ];

Phone *phone = persion.phone;

Battery *battery = phone.battery;

一:使用KVC

Battery *battery = [persion valueForKeyPath: @"phone.battery" ];

注意- valueForKeyPath 里面的值是區分大小寫的,你如果寫出Phone.Battery 是不行的.

KVC 最常用的還是在序列化和反序列話對象。我們經常需要把json字符串反序列化成我們想要的對象 下面是一個例子 將字典用NSKeyedArchiver 序列化成對象

- (id)initWithDictionary:(NSDictionary *)dictionary {

self = [self init];

if (self){

[self setValuesForKeysWithDictionary:dictionary];

}

return self;

}

注意 這里有一個坑 當我們setValue 給一個沒有定義的字典值(forUndefinedKey)時 會拋出NSUndefinedKeyException異常的 記的處理此種情況.

還有一個需要注意的是KVC 并沒有類型檢驗,畢竟Object-C 還是動態的啦。 還是看下面的代碼吧

[persion setValue:[NSNumber numberWithInteger:1] forKey:@"name"];

// compiles and runs

persion.name = [NSNumber numberWithInteger:1];

// won't compile: Incompatible pointer types assigning to 'NSString *' from 'NSNumber *'

setValue forKey 得到的對象是泛型的id, 只有在使用的時候才能確定類型。你可能會問不至于吧 OC 這樣弱啊,當然不是 OC 提供了了一個方法validateValue來解決這個問題

@property (nonatomic, strong) NSString name;

- (BOOL)validateName:(id*)ioValue error:(NSError**)error {

// Validation logic goes here

}

Person *p = [Person new];

NSString *name = @"Jason Hu";

NSError *error = nil;

// This call below actually calls our validateName: error: method

if ([p validateValue:&name forKey:@"name" error:&error]) {

[p setValue:name forKey:@"name"];

}

你可能會問寫這樣多代碼 才只驗證了一個屬性 那如果我這個類有n+個屬性 難道我要寫n+個驗證方法嗎?

二:KVC 驗證

到這里我們對KVC已經有了一個初步印象,到這里其實還只是冰山一角。

下面我們要提高更高的要求,如果讓key 支持 不區分大小寫

下面我們提到一個方法initialize

initialize是在類或者其子類的第一個方法被調用前調用。所以如果類沒有被引用進項目或者類文件被引用進來,但是沒有使用,那么initialize也不會被調用 ,到這里 知道我們接下來要干嘛了吧

+ (void)initialize {

[super initialize];

dispatch_once(&onceToken, ^{

modelProperties = [NSMutableDictionary dictionary];

propertyTypesArray = @[/* removed for brevity */];

});

NSMutableDictionary *translateNameDict = [NSMutableDictionary dictionary];

[self hydrateModelProperties:[self class] translateDictionary:translateNameDict];

[modelProperties setObject:translateNameDict forKey:[self calculateClassName]];

}

+ (void)hydrateModelProperties:(Class)class translateDictionary:(NSMutableDictionary *)translateDictionary {

if (!class || class == [NSObject class]){

return;

}

unsigned int outCount, i;

objc_property_t *properties = class_copyPropertyList(class, &outCount);

for (i = 0; i < outCount; i++){

objc_property_t p = properties[i];

const char *name = property_getName(p);

NSString *nsName = [[NSString alloc] initWithCString:name encoding:NSUTF8StringEncoding];

NSString *lowerCaseName = [nsName lowercaseString];

[translateDictionary setObject:nsName forKey:lowerCaseName];

//注意此處哦

NSString *propertyType = [self getPropertyType:p];

[self addValidatorForProperty:nsName type:propertyType];

}

free(properties);

[self hydrateModelProperties:class_getSuperclass(class) translateDictionary:translateDictionary];

}

KVO

Key-Value Observing (簡寫為KVO):當指定的對象的屬性被修改了,允許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察者,相當于設計模式中的觀察者模式。

KVO的優點:

當有屬性改變,KVO會提供自動的消息通知。這樣的架構有很多好處。首先,開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送消息通知。這是KVO 機制提供的最大的優點。因為這個方案已經被明確定義,獲得框架級支持,可以方便地采用。開發人員不需要添加任何代碼,不需要設計自己的觀察者模型,直接可 以在工程里使用。其次,KVO的架構非常的強大,可以很容易的支持多個觀察者觀察同一個屬性,以及相關的值。

KVO是Key Value Observer的縮寫,主要方法是addObserver:forKeyPath:options:context:和observeValueForPath:ofObject:change:context。

addObserver:forKeyPath:options:context:注冊監聽事件。

observeValueForPath:ofObject:change:context當注冊的值,利用KVC發生改變的時候,就會觸發這個方法。

在最后的dealloc方法里面,要記得移除監聽事件。

補充:iOS之KVC和KVO

一、KVC(key-value-coding)

1、只針對類屬性,設置鍵值對

2、設置setValue: forKey:,即forKey只能為類屬性

3、取值valueForKey

二、KVO(key-value-observing)被觀察者的屬性發生改變時,通知觀察者

1、利用KVC對類屬性進行設置

2、注冊observing對象addObserver:forKeyPath:options:context:

3、觀察者類必須重寫方法?observeValueForKeyPath:ofObject:change:context:

4、應用,MVC模型中,數據庫(dataModal)發生變化時,引起view改變,用這種方式實現非常方便

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

推薦閱讀更多精彩內容

  • KCV 其實由于ObjC的語言特性,你根部不必進行任何操作就可以進行屬性的動態讀寫,這種方式就是Key Value...
    TYM閱讀 1,062評論 0 4
  • 前言: 本文基本不講KVC/KVO的用法,只結合網上的資料說說對這種技術的理解。 由于KVO內容較少,而且是以KV...
    土b蘭博王閱讀 3,079評論 0 33
  • KVC(Key-value coding)鍵值編碼,單看這個名字可能不太好理解。其實翻譯一下就很簡單了,就是指iO...
    朽木自雕也閱讀 1,571評論 6 1
  • 1.KVC底層是通過runtime對method和value操作 比如說如下的一行KVC的代碼: [sit set...
    smart_small閱讀 849評論 0 0
  • 一、KVC 通過關鍵字,訪問屬性及成員變量。1.kvc當調用setValue:屬性值 forKey:@”name“...
    doudo閱讀 326評論 0 0