KVC & KVO

1 .KVC(Key Value Coding)

鍵值編碼方法,可以給屬性,甚至是私有屬性進行賦值和取值,簡化字典—>模型,以及模型—>字典的轉(zhuǎn)變;

(1) 對屬性進行賦值,類似于setter方法;以及字典—>模型;

<1> 對模型中簡單屬性賦值;

GMQPerson *p = [[GXQPerson alloc] init];

p.dog = [[GMQDog alloc] init];

[p setValue:@"GMQ"forKey:@"name”]; —>keyPath的功能比key的功能更強大

[p.dog setValue:@"wangcai" forKey:@"name"];

<2> 對復雜嵌套的屬性賦值,

[p setValue:@"wangcai" forKey:@"dog.name"];//注意:? 錯誤寫法!!!人對象中沒有dog.name這個屬性

[p.dog setValue:@"wangcai" forKeyPath:@“name"];//正確

[p setValue:@"wangcai" forKeyPath:@"dog.name"];// 按照路徑找到相應的屬性

<3>核心功能,可以對私有成員變量進行賦值;

[p setValue:@"1.79" forKeyPath:@"_height”];// 經(jīng)測試,這里既可以寫成_height,也可以寫成height;

<4> 簡化字典—>模型的操作;

NSDictionary *dict = @{

@"name" : @"GMQ",

@"age" : @"23",

@"no" : @"123456"

};

這一條語句相當于下面的幾句,將字典中的每一個鍵值對拆開,分別賦值給模型中的每一個屬性;需要注意的是如果字典中有一個key是模型中沒有的屬性,那么用這條語句運行時就會報錯。

[p setValuesForKeysWithDictionary:dict];;

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

[p setValue:@"23" forKey:@"age"];

[p setValue:@"123456" forKey:@"no"];//no是字典中的key值,但是在模型中沒有這個屬性,會報錯。


(2) 對屬性進行取值,類似于getter方法;以及模型—>字典;

<1> 對模型中簡單屬性取值;

[p valueForKeyPath:@"name”];

<2> 對復雜嵌套的屬性取值,

[p valueForKeyPath:@“dog.name”];

<3>核心功能,可以對私有成員變量進行取值;

NSLog(@"%@",[p valueForKeyPath:@"_height"]);

<4> 簡化模型—>字典的操作;

GXQPerson*p = [[GXQPersonalloc]init];

p.name=@"jack";

p.age=20;

NSDictionary*dict = [p dictionaryWithValuesForKeys:@[@"name",@"age"]];

還有一些其他的方法:

NSArray*arr =@[p, p1, p2];

NSArray*names = [arr valueForKeyPath:@"name”];// 返回一個所有的name屬性的值組成的數(shù)組;

NSLog(@"%@",[arr valueForKeyPath:@"@avg.age"]);// 引號內(nèi)的@是一個運算符,這里算出的是數(shù)組中所有元素的年齡屬性的值的平均值;

[p setValue:<#(nullable id)#>forUndefinedKey:<#(nonnull NSString *)#>];// 這是系統(tǒng)才能調(diào)用的方法;

2 .KVO(Key Value Observing)

鍵值監(jiān)聽/鍵值觀察;可以監(jiān)聽模型屬性值的變化;只要模型屬性值一有變化,就會調(diào)用監(jiān)視方法,屬于即時調(diào)用;還有一點,在被監(jiān)視對象將要銷毀前,一定要移除監(jiān)聽,否則程序會報錯。

GMQPerson*p = [[GMQ Personalloc]init];

p.name=@"GMQ";

[p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingNew | NSKeyValueObservingOld context:@"haha"];

// 給p添加一個監(jiān)聽器,self代表控制器,也可以是其他類的對象,如果是其他類,則一定要把監(jiān)視方法寫到那個類中;

// keyPath 表示監(jiān)聽的是哪個屬性;

//?options是個枚舉值,根據(jù)options傳入的數(shù)據(jù),會在監(jiān)聽方法的change字典中賦予相應的值;

p.name=@"xiaoming”;// 即時調(diào)用,因此會調(diào)用兩次監(jiān)聽方法;

p.name=@"xiaohong";

[p removeObserver:self forKeyPath:@"name”];// 在被監(jiān)聽的對象銷毀前,一定移除監(jiān)聽,否則運行會報錯;

}

// 下面是監(jiān)聽的方法,每次屬性值改變都會調(diào)用,即使賦予的值相同,也會調(diào)用

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void

*)context

{

// keyPath:是監(jiān)聽的哪個屬性的變化;

// object:表示的是監(jiān)聽的哪個對象的屬性改變了

//change是個字典,根據(jù)上面options傳入的數(shù)據(jù),給對應的key賦值

//context:添加監(jiān)聽器中傳入的參數(shù)

//??? NSLog(@"%@,%@,%@,%@",keyPath,object,change,context);

NSLog(@"%@",change[NSKeyValueChangeNewKey]);//取出字典中key為NSKeyValueChangeNewKey的值,表示更改后的值;對應

NSKeyValueObservingOptionNew;

NSLog(@"%@",change[NSKeyValueChangeOldKey]);// 取出字典中key為NSKeyValueChangeOldKey的值,表示更改后的值;對應

NSKeyValueObservingOptionOld;

}


3.KVC和KVO的區(qū)別和聯(lián)系:

KVC的主要作用:給模型中的屬性賦值和取值

KVO的主要作用:監(jiān)聽模型中屬性值的改變

KVC是路徑訪問的規(guī)范,KVO則是觀察某個變量的變化過程

KVC/KVO類似于代理,通知,都是一種通訊方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

  • KCV 其實由于ObjC的語言特性,你根部不必進行任何操作就可以進行屬性的動態(tài)讀寫,這種方式就是Key Value...
    TYM閱讀 1,065評論 0 4
  • KVC(Key-Value Coding) KVC最常見的兩個用途: 給私有的成員變量賦值(當然公有的也可以)比如...
    ForeverYoung21閱讀 1,179評論 1 15
  • KVC 和 KVO KVC 鍵值對編碼,簡單來說,就是控制一切鍵值對,作用分為 setter 和 getter方法...
    娘親Joanna閱讀 311評論 1 4
  • KVC KVC是key Value Coding的縮寫,主要方法有setValue:forKey和valueFor...
    小暖風閱讀 383評論 0 1
  • 原文kvc kvo KVC 概論 KVC(全稱 key-value-coding)即鍵值編碼。KVC 的操作方法由...
    一代驕馬閱讀 151評論 0 1