KVC/KVO 使用细节和调用顺序
生活随笔
收集整理的這篇文章主要介紹了
KVC/KVO 使用细节和调用顺序
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Key-Value Coding (KVC) Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一個(gè)非正式的 Protocol,提供一種機(jī)制來(lái)間接訪問(wèn)對(duì)象的屬性。KVO 就是基于 KVC 實(shí)現(xiàn)的關(guān)鍵技術(shù)之一。 一個(gè)對(duì)象擁有某些屬性。比如說(shuō),一個(gè) Person 對(duì)象有一個(gè) name 和一個(gè) address 屬性。以 KVC 說(shuō)法,Person 對(duì)象分別有一個(gè) value 對(duì)應(yīng)他的 name 和 address 的 key。 key 只是一個(gè)字符串,它對(duì)應(yīng)的值可以是任意類型的對(duì)象。從最基礎(chǔ)的層次上看,KVC 有兩個(gè)方法:一個(gè)是設(shè)置 key 的值,另一個(gè)是獲取 key 的值。 // 重寫setter方法和getter 方法: 1. Dog對(duì)象有屬性: @property(nonatomic,copy)NSString?*name; 2. 如果同時(shí)重寫setter和getter方法: // 記住: 如果同時(shí)重寫setter和getter方法,系統(tǒng)不會(huì)自動(dòng)生成_name的成員變量. 需要??@synthesize?name =?_name; 以告訴系統(tǒng),你要幫我生成_name? 3.??[myDog?setValue:@"MBXxx"?forKey:@"_name"]; @“_name” @“name”?都可以訪問(wèn)到該成員變量 4.??NSString?*age = [myDog?valueForKey:@"age"]; 調(diào)用這句代碼時(shí), 1) 系統(tǒng)先去找該變量有沒(méi)有g(shù)etter方法. 如果有,調(diào)用getter方法取值 2) 如果沒(méi)有g(shù)etter方法,系統(tǒng)會(huì)查找有沒(méi)有age成員或者_(dá)age成員. 5. 如果僅僅在.m文件中聲明了全局的變量: {
????@public NSString?*age; } 這時(shí),只能通過(guò)KVC模式來(lái)賦值和取值. // 注: 先賦值,再取. [myDog?setValue:@"10"?forKey:@"age"];
????????NSString?*age = [myDog?valueForKey:@"age"]; NSLog(@"age ==== %@",age); 打印結(jié)果: age === 10 說(shuō)明,賦值和取值過(guò)程成功.
KVO: 即:Key-Value Observing,它提供一種機(jī)制,當(dāng)指定的對(duì)象的屬性被修改后,則對(duì)象就會(huì)接受到通知。簡(jiǎn)單的說(shuō)就是每次指定的被觀察的對(duì)象的屬性被修改后,KVO就會(huì)自動(dòng)通知相應(yīng)的觀察者了。 // dog.m?代碼: #import?"Dog.h" @implementation?Dog
{
????@public NSString?*age; } @synthesize?name =?_name; -(void)setName:(NSString?*)name{?// 1 NSLog(@"xxxxx"); _name?= name; } -(NSString?*)name{?// 2
????NSLog(@"AAAAA");
????return?_name; } @end
person.m 代碼: #import?"Person.h"
@implementation?Person
-(void)setDog:(Dog?*)dog{?// 3
????_dog?= dog;
????//?添加當(dāng)前對(duì)象為觀察者
??? [_dog?addObserver:self?forKeyPath:@"name"?options:NSKeyValueObservingOptionNew?|?NSKeyValueObservingOptionOld?context:@"hello kvo"];
}
-(void)dealloc{?// 6
??? [_dog?removeObserver:self?forKeyPath:@"name"]; } -(void)observeValueForKeyPath:(NSString?*)keyPath ofObject:(id)object change:(NSDictionary?*)change context:(void?*)context{?// 4 NSLog(@"context==%@",context); if([object?isKindOfClass:[Dog?class]] && [keyPath?isEqualToString:@"name"]){ NSString?*new = change[NSKeyValueChangeNewKey];
????????NSLog(@"new === %@",new);
??? }
} @end 下面看看調(diào)用過(guò)程是怎樣的? Person?*p = [[Person?alloc]init];
??????? p.dog?= myDog; myDog.name?=?@"fyz”;?//5 1)調(diào)用?p.dog?= myDog; 方法時(shí),走 方法3. 2)然后來(lái)到 方法5 3)來(lái)到 方法2(getter) //打印了AAAA 4)然后 來(lái)到 方法1(setter) // 打印XXXX?(這里為什么?需要測(cè)試) 5 ) 又來(lái)到 方法2( getter ) //打印了AAAA?(這里又為什么?需要測(cè)試) 6 ) 然后來(lái)到 方法4 // 打印new === 7 ) 最后走析構(gòu)函數(shù) 方法6 // 沒(méi)有加入觀察者模式時(shí),只會(huì)調(diào)一次 方法1(set方法),相當(dāng)于觀察者模式的存在. 先調(diào)用了一次getter方法, 再調(diào)一次setter方法,再調(diào)一次getter方法.
????@public NSString?*age; } 這時(shí),只能通過(guò)KVC模式來(lái)賦值和取值. // 注: 先賦值,再取. [myDog?setValue:@"10"?forKey:@"age"];
????????NSString?*age = [myDog?valueForKey:@"age"]; NSLog(@"age ==== %@",age); 打印結(jié)果: age === 10 說(shuō)明,賦值和取值過(guò)程成功.
KVO: 即:Key-Value Observing,它提供一種機(jī)制,當(dāng)指定的對(duì)象的屬性被修改后,則對(duì)象就會(huì)接受到通知。簡(jiǎn)單的說(shuō)就是每次指定的被觀察的對(duì)象的屬性被修改后,KVO就會(huì)自動(dòng)通知相應(yīng)的觀察者了。 // dog.m?代碼: #import?"Dog.h" @implementation?Dog
{
????@public NSString?*age; } @synthesize?name =?_name; -(void)setName:(NSString?*)name{?// 1 NSLog(@"xxxxx"); _name?= name; } -(NSString?*)name{?// 2
????NSLog(@"AAAAA");
????return?_name; } @end
person.m 代碼: #import?"Person.h"
@implementation?Person
-(void)setDog:(Dog?*)dog{?// 3
????_dog?= dog;
????//?添加當(dāng)前對(duì)象為觀察者
??? [_dog?addObserver:self?forKeyPath:@"name"?options:NSKeyValueObservingOptionNew?|?NSKeyValueObservingOptionOld?context:@"hello kvo"];
}
-(void)dealloc{?// 6
??? [_dog?removeObserver:self?forKeyPath:@"name"]; } -(void)observeValueForKeyPath:(NSString?*)keyPath ofObject:(id)object change:(NSDictionary?*)change context:(void?*)context{?// 4 NSLog(@"context==%@",context); if([object?isKindOfClass:[Dog?class]] && [keyPath?isEqualToString:@"name"]){ NSString?*new = change[NSKeyValueChangeNewKey];
????????NSLog(@"new === %@",new);
??? }
} @end 下面看看調(diào)用過(guò)程是怎樣的? Person?*p = [[Person?alloc]init];
??????? p.dog?= myDog; myDog.name?=?@"fyz”;?//5 1)調(diào)用?p.dog?= myDog; 方法時(shí),走 方法3. 2)然后來(lái)到 方法5 3)來(lái)到 方法2(getter) //打印了AAAA 4)然后 來(lái)到 方法1(setter) // 打印XXXX?(這里為什么?需要測(cè)試) 5 ) 又來(lái)到 方法2( getter ) //打印了AAAA?(這里又為什么?需要測(cè)試) 6 ) 然后來(lái)到 方法4 // 打印new === 7 ) 最后走析構(gòu)函數(shù) 方法6 // 沒(méi)有加入觀察者模式時(shí),只會(huì)調(diào)一次 方法1(set方法),相當(dāng)于觀察者模式的存在. 先調(diào)用了一次getter方法, 再調(diào)一次setter方法,再調(diào)一次getter方法.
轉(zhuǎn)載于:https://www.cnblogs.com/toxicanty/p/4453109.html
總結(jié)
以上是生活随笔為你收集整理的KVC/KVO 使用细节和调用顺序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Android-功能】Android应
- 下一篇: BCP 导入导出数据库数据