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

前言

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

KVC用法

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

  • setValue:forKey:(為對象的屬性賦值)
  • setValue: forKeyPath:(為對象的屬性賦值(包含了setValue:forKey:的功能姻报,并且還可以對對象內(nèi)的類的屬性進行賦值))
  • valueForKey:(根據(jù)key取值)
  • valueForKeyPath:(根據(jù)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中調(diào)用
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);
}

有幾個小點,我也是在敲代碼的時候發(fā)現(xiàn)的间螟。

  • 在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;你會發(fā)現(xiàn)value的值必須是id,也就是說不能傳基本數(shù)據(jù)類型,必須是指針類型的變量见坑。
KVC和對象的setter仙辟、getter方法的區(qū)別

一般情況下,KVC和setter鳄梅、getter應該說都能達到對對象屬性的賦值叠国,并且KVC操作也是去調(diào)用的setter方法和getter方法(針對一些已經(jīng)在.h中聲明的屬性而言)。但是對于一些私有屬性戴尸,那么這個時候setter粟焊、getter方法就沒有用了,這個時候KVC卻能發(fā)揮重要優(yōu)勢孙蒙。
例如:在Person.m中
#import "Person.h"
@implementation Person
{
NSInteger _height;
}
@end
此時你會發(fā)現(xiàn)setter项棠、getter已經(jīng)無能為力了,但是KVC去可以實現(xiàn)賦值挎峦、取值

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

keyPath方法是集成了key的所有功能香追,也就是說對一個對象的一般屬性進行賦值、取值坦胶,兩個方法是通用的透典,都可以實現(xiàn)。但是對對象中的對象進的屬性行賦值顿苇,只有keyPath能夠?qū)崿F(xiàn)峭咒。

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

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

  • 添加觀察者
  • 在觀察者中實現(xiàn)監(jiān)聽方法,observeValueForKeyPath: ofObject: change: context:(通過查閱文檔可以知道幔翰,絕大多數(shù)對象都有這個方法漩氨,因為這個方法屬于NSObject)
  • 移除觀察者
//讓對象b監(jiān)聽對象a的name屬性
//options屬性可以選擇是哪個
 /* NSKeyValueObservingOptionNew =0x01, 新值 
  * NSKeyValueObservingOptionOld =0x02, 舊值 
  */ 
[a addObserver:b forKeyPath:@"name"options:kNilOptionscontext:nil]; 
a.name = @"zzz";
#pragma mark - 實現(xiàn)KVO回調(diào)方法
/* * 當對象的屬性發(fā)生改變會調(diào)用該方法
    * @param keyPath 監(jiān)聽的屬性 
    * @param object 監(jiān)聽的對象 
    * @param change 新值和舊值 
    * @param context 額外的數(shù)據(jù) 
*/
- (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指針,會在隨后的簡述中介紹)

當一個類的屬性被觀察的時候叫惊,系統(tǒng)會通過runtime動態(tài)的創(chuàng)建一個該類的派生類款青,并且會在這個類中重寫基類被觀察的屬性的setter方法,而且系統(tǒng)將這個類的isa指針指向了派生類赋访,從而實現(xiàn)了給監(jiān)聽的屬性賦值時調(diào)用的是派生類的setter方法。重寫的setter方法會在調(diào)用原setter方法前后缓待,通知觀察對象值得改變蚓耽。
??具體實現(xiàn)圖如下,這里我拿的是iOS程序猿的圖旋炒,借用一下應該沒關系吧步悠?


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

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


0.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市尚粘,隨后出現(xiàn)的幾起案子择卦,更是在濱河造成了極大的恐慌,老刑警劉巖郎嫁,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秉继,死亡現(xiàn)場離奇詭異,居然都是意外死亡泽铛,警方通過查閱死者的電腦和手機尚辑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盔腔,“玉大人杠茬,你說我怎么就攤上這事〕谒妫” “怎么了澈蝙?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撵幽。 經(jīng)常有香客問我灯荧,道長,這世上最難降的妖魔是什么盐杂? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任逗载,我火速辦了婚禮哆窿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘厉斟。我一直安慰自己挚躯,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布擦秽。 她就那樣靜靜地躺著码荔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪感挥。 梳的紋絲不亂的頭發(fā)上缩搅,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音触幼,去河邊找鬼硼瓣。 笑死,一個胖子當著我的面吹牛置谦,可吹牛的內(nèi)容都是我干的堂鲤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼媒峡,長吁一口氣:“原來是場噩夢啊……” “哼瘟栖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谅阿,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤慢宗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奔穿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镜沽,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年贱田,在試婚紗的時候發(fā)現(xiàn)自己被綠了缅茉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡男摧,死狀恐怖蔬墩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耗拓,我是刑警寧澤拇颅,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站乔询,受9級特大地震影響樟插,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一黄锤、第九天 我趴在偏房一處隱蔽的房頂上張望搪缨。 院中可真熱鬧,春花似錦鸵熟、人聲如沸副编。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痹届。三九已至,卻和暖如春打月,著一層夾襖步出監(jiān)牢的瞬間队腐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工僵控, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留香到,地道東北人鱼冀。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓报破,卻偏偏與公主長得像,于是被迫代替她去往敵國和親千绪。 傳聞我的和親對象是個殘疾皇子充易,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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