KVC、KVO探識(一)KVO和KVO的詳細使用

前言

最近一直在做原型圖,中間有兩天沒有寫簡書了。感覺心里面特別不是滋味。所以今天好不容易忙中偷閑,所以今天必須寫幾篇簡書,安慰一下自己的內心。于是今天給大家分享一下KVC和KVO的簡單用法,隨后會更加深層次的去寫一系列的簡書,去深層次的講解KVC和KVO。

KVC用法

KVC也就是key-value-coding(鍵值編碼),簡而言之就是通過key值去進行賦值和取值。主要是是操作對象的屬性。以下是幾個常用的方法:

  • setValue:forKey:(為對象的屬性賦值)
  • setValue: forKeyPath:(為對象的屬性賦值(包含了setValue:forKey:的功能,并且還可以對對象內的類的屬性進行賦值))
  • valueForKey:(根據key取值)
  • valueForKeyPath:(根據keyPath取值)
  • setValuesForKeysWithDictionary:(對模型進行一次性賦值)
幾種方法的詳盡用法

例如:生成一個這樣子的對象Person
person.h

@class Car;
@interface Person : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,strong)Car *car;
@end

Car.h

@interface Car : NSObject
@property (nonatomic,strong) NSNumber *price;
@end

在ViewController.m中調用
ViewController.m

- (void)viewDidLoad {
      [super viewDidLoad];
      Person *person=[[Person alloc]init];
      [person setValue:@"lxh" forKey:@"name"];
      float price=100.0;
      Car *car=[[Car alloc]init];
      person.car=car;
      [person setValue:[NSNumber numberWithFloat:price] forKeyPath:@"car.price"];
      NSLog(@"%@",person.name);

      NSLog(@"%f",car.price.floatValue);
}

有幾個小點,我也是在敲代碼的時候發現的。

  • 在Person中我僅僅只是聲明了@class Car,而沒有引用#import "Car.h",然后在ViewController.m中便可以對其進行: [person setValue:[NSNumber numberWithFloat:price] forKeyPath:@"car.price"];這樣子的賦值。所以說明KVC會去自動查找Car類進行賦值。
  • 在對person.car進行賦值的時候,必須保證car變量的存在,也就是說,必須生成一個Car對象賦值給person.car.否則會拋出野指針異常錯誤。
  • 還有就是setValue:forKey:和setValue: forKeyPath:這兩個方法,可以查看NSObject中的聲明:- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;你會發現value的值必須是id,也就是說不能傳基本數據類型,必須是指針類型的變量。
KVC和對象的setter、getter方法的區別

一般情況下,KVC和setter、getter應該說都能達到對對象屬性的賦值,并且KVC操作也是去調用的setter方法和getter方法(針對一些已經在.h中聲明的屬性而言)。但是對于一些私有屬性,那么這個時候setter、getter方法就沒有用了,這個時候KVC卻能發揮重要優勢。
例如:在Person.m中
#import "Person.h"
@implementation Person
{
NSInteger _height;
}
@end
此時你會發現setter、getter已經無能為力了,但是KVC去可以實現賦值、取值

[p setValue:@170 forKey:@"height"];
key和keyPath的區別

keyPath方法是集成了key的所有功能,也就是說對一個對象的一般屬性進行賦值、取值,兩個方法是通用的,都可以實現。但是對對象中的對象進的屬性行賦值,只有keyPath能夠實現。

setValuesForKeysWithDictionary:的巧妙使用(字典轉模型)
-(instancetype)initWithDict:(NSDictionary *)dict{
         if (self = [super init]) {
               [self setValuesForKeysWithDictionary:dict]; 
          } 
         return self;
}
注意點:
  • 字典轉模型的時候,字典中的某一個key一定要在模型中有對應的屬性
  • 如果一個模型中包含了另外的模型對象,是不能直接轉化成功的。
  • 通過kvc轉化模型中的模型,也是不能直接轉化成功的。
KVO的用法

KVO也就是key-value-observing(即鍵值觀察),利用一個key來找到某個屬性并監聽其值得改變。用法如下:

  • 添加觀察者
  • 在觀察者中實現監聽方法,observeValueForKeyPath: ofObject: change: context:(通過查閱文檔可以知道,絕大多數對象都有這個方法,因為這個方法屬于NSObject)
  • 移除觀察者
//讓對象b監聽對象a的name屬性
//options屬性可以選擇是哪個
 /* NSKeyValueObservingOptionNew =0x01, 新值 
  * NSKeyValueObservingOptionOld =0x02, 舊值 
  */ 
[a addObserver:b forKeyPath:@"name"options:kNilOptionscontext:nil]; 
a.name = @"zzz";
#pragma mark - 實現KVO回調方法
/* * 當對象的屬性發生改變會調用該方法
    * @param keyPath 監聽的屬性 
    * @param object 監聽的對象 
    * @param change 新值和舊值 
    * @param context 額外的數據 
*/
- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary<NSString *,id>*)change context:(void *)context{ 
    NSLog(@"%@的值改變了,",keyPath); 
    NSLog(@"change:%@", change);
}
//最后不要忘記了,去移除observer
- (void)dealloc{ 
       [a removeObserver:b forKeyPath:@"name"];
  }
KVO底層(這部分涉及到了runtime,關于isa指針,會在隨后的簡述中介紹)

當一個類的屬性被觀察的時候,系統會通過runtime動態的創建一個該類的派生類,并且會在這個類中重寫基類被觀察的屬性的setter方法,而且系統將這個類的isa指針指向了派生類,從而實現了給監聽的屬性賦值時調用的是派生類的setter方法。重寫的setter方法會在調用原setter方法前后,通知觀察對象值得改變。
??具體實現圖如下,這里我拿的是iOS程序猿的圖,借用一下應該沒關系吧?


今天僅僅是KVO和KVC的簡單的用法的介紹,隨后會更加深層次的進行介紹,敬請期待.....、

歡迎關注我的個人微信公眾號,免費送計算機各種最新視頻資源!你想象不到的精彩!


0.jpg
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念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

推薦閱讀更多精彩內容