在iOS開發(fā)中屋剑,我們常常用到鍵值編碼KVC和鍵值監(jiān)聽KVO兩個東東润匙,今天小編和大家分享的就是這兩個東東在應(yīng)用開發(fā)中的具體用法。下面是小編在網(wǎng)上看到的一位大牛寫的唉匾,灰常不錯的有關(guān)KVC和KVO的介紹孕讳,既然大牛都寫得這么詳細(xì)了,我們就直接借鑒借鑒吧巍膘。
鍵值編碼KVC
KVC的操作方法由NSKeyValueCoding協(xié)議提供厂财,而NSObject就實現(xiàn)了這個協(xié)議,也就是說objective-c語言中幾乎所有的對象都支持KVC操作峡懈,常用的KVC操作方法如下:
1璃饱、動態(tài)設(shè)置:setValue:屬性值forKey:屬性名(用于簡單路徑)、setValue:屬性值forKeyPath:屬性路徑(用于復(fù)合路徑逮诲,例如Person有一個Account類型的屬性帜平,那么person.account就是一個復(fù)合屬性)
2幽告、動態(tài)讀取:valueForKey:屬性名裆甩、valueForKeyPath:屬性名(用于復(fù)合路徑)
下面舉個栗子來看看KVC的具體用法吧
Account.h
#import
@interfaceAccount : NSObject
#pragma mark -屬性
#pragma mark余額
@property(nonatomic,assign) float balance;
@end
Account.m
#import"Account.h"
@implementationAccount
@end
Person.h
#import
@class Account;
@interfacePerson : NSObject{
@private
int _age;
}
#pragma mark -屬性
#pragma mark姓名
@property(nonatomic,copy) NSString *name;
#pragma mark賬戶
@property(nonatomic,retain) Account *account;
#pragma mark -公共方法
#pragma mark顯示人員信息
-(void)showMessage;
@end
Person.m
#import"Person.h"
@implementationPerson
#pragma mark -公共方法
#pragma mark顯示人員信息
-(void)showMessage{
NSLog(@"name=%@,age=%d",_name,_age);
}
@end
main.m
#import
#import"Person.h"
#import"Account.h"
int main(intargc, const char * argv[]) {
@autoreleasepool {
Person *person1=[[Person alloc]init];
[person1 setValue:@"Kenshin"forKey:@"name"];
[person1 setValue:@28forKey:@"age"];//注意即使一個私有變量仍然可以訪問
[person1 showMessage];
//結(jié)果:name=Kenshin,age=28
NSLog(@"person1's name is :%@,ageis :%@",person1.name,[person1 valueForKey:@"age"]);
//結(jié)果:person1's name is :Kenshin,age is :28
Account *account1=[[Accountalloc]init];
person1.account=account1;//注意這一步一定要先給account屬性賦值冗锁,否則下面按路徑賦值無法成功,因為account為nil嗤栓,當(dāng)然這一步驟也可以寫成:[person1setValue:account1 forKeyPath:@"account"];
[person1 setValue:@100000000.0forKeyPath:@"account.balance"];
NSLog(@"person1's balance is:%.2f",[[person1 valueForKeyPath:@"account.balance"]floatValue]);
//結(jié)果:person1's balance is :100000000.00
}
return 0;
}
KVC使用起來比較簡單冻河,但是它如何查找一個屬性進(jìn)行讀取呢?具體查找規(guī)則(假設(shè)現(xiàn)在要利用KVC對a進(jìn)行讀溶运А)如下:
1)如果是動態(tài)設(shè)置屬性叨叙,則優(yōu)先考慮調(diào)用setA方法,如果沒有該方法則優(yōu)先考慮搜索成員變量_a堪澎,如果仍然不存在則搜索成員變量a擂错,如果最后仍然沒搜索到則會調(diào)用這個類的setValue:forUndefinedKey:方法(注意搜索過程中不管這些方法、成員變量是私有的還是公共的都能正確設(shè)置)樱蛤;
2)如果是動態(tài)讀取屬性钮呀,則優(yōu)先考慮調(diào)用a方法(屬性a的getter方法),如果沒有搜索到則會優(yōu)先搜索成員變量_a昨凡,如果仍然不存在則搜索成員變量a爽醋,如果最后仍然沒搜索到則會調(diào)用這個類的valueforUndefinedKey:方法(注意搜索過程中不管這些方法、成員變量是私有的還是公共的都能正確讀取)便脊;
鍵值監(jiān)聽KVO
KVO其實是一種觀察者模式蚂四,在objective-c中原生就支持這種機(jī)制,它叫做Key Value Observing(簡稱KVO)哪痰,利用它可以很容易實現(xiàn)視圖組件和數(shù)據(jù)模型的分離遂赠,當(dāng)數(shù)據(jù)模型的屬性值改變之后作為監(jiān)聽器的視圖組件就會被激發(fā),激發(fā)時就會回調(diào)監(jiān)聽器自身晌杰。在OC中要實現(xiàn)KVO則必須實現(xiàn)NSKeyValueObServing協(xié)議解愤,不過幸運(yùn)的是NSObject已經(jīng)實現(xiàn)了該協(xié)議,因此幾乎所有的OC對象都可以使用KVO乎莉。
在ObjC中使用KVO操作常用的方法如下:
1送讲、注冊指定Key路徑的監(jiān)聽器:addObserver: forKeyPath: options:context:
2、刪除指定Key路徑的監(jiān)聽器:removeObserver: forKeyPath惋啃、removeObserver: forKeyPath: context:
3哼鬓、回調(diào)監(jiān)聽:observeValueForKeyPath: ofObject:change: context:
KVO的使用步驟也比較簡單:
1.通過addObserver: forKeyPath: options: context:為被監(jiān)聽對象(它通常是數(shù)據(jù)模型)注冊監(jiān)聽器
2.重寫監(jiān)聽器的observeValueForKeyPath: ofObject: change:
context:方法
假設(shè)當(dāng)我們的賬戶余額balance變動之后我們希望用戶可以及時獲得通知。那么此時Account就作為我們的被監(jiān)聽對象边灭,需要Person為它注冊監(jiān)聽(使用addObserver: forKeyPath: options:
context:);而人員Person作為監(jiān)聽器需要重寫它的observeValueForKeyPath: ofObject: change: context:方法异希,當(dāng)監(jiān)聽的余額發(fā)生改變后會回調(diào)監(jiān)聽器Person監(jiān)聽方法(observeValueForKeyPath: ofObject: change:
context:)。下面通過代碼模擬上面的過程:
Account.h
#import
@interfaceAccount : NSObject
#pragma mark -屬性
#pragma mark余額
@property(nonatomic,assign) float balance;
@end
Account.m
#import"Account.h"
@implementationAccount
@end
Person.h
#import
@class Account;
@interfacePerson : NSObject{
@private
int _age;
}
#pragma mark -屬性
#pragma mark姓名
@property(nonatomic,copy) NSString *name;
#pragma mark賬戶
@property(nonatomic,retain) Account *account;
#pragma mark -公共方法
#pragma mark顯示人員信息
-(void)showMessage;
@end
Person.m
#import"Person.h"
#import"Account.h"
@implementationPerson
#pragma mark -公共方法
#pragma mark顯示人員信息
-(void)showMessage{
NSLog(@"name=%@,age=%d",_name,_age);
}
#pragma mark設(shè)置人員賬戶
-(void)setAccount:(Account*)account{
_account=account;
//添加對Account的監(jiān)聽
[self.account addObserver:selfforKeyPath:@"balance" options:NSKeyValueObservingOptionNewcontext:nil];
}
#pragma mark -覆蓋方法
#pragma mark重寫observeValueForKeyPath方法绒瘦,當(dāng)賬戶余額變化后此處獲得通知
-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{
if([keyPathisEqualToString:@"balance"]){//這里只處理balance屬性
NSLog(@"keyPath=%@,object=%@,newValue=%.2f,context=%@",keyPath,object,[[changeobjectForKey:@"new"] floatValue],context);
}
}
#pragma mark重寫銷毀方法
-(void)dealloc{
[self.account removeObserver:selfforKeyPath:@"balance"];//移除監(jiān)聽
//[super dealloc];//注意啟用了ARC称簿,此處不需要調(diào)用
}
@end
main.m
#import
#import"Person.h"
#import"Account.h"
int main(intargc, const char * argv[]) {
@autoreleasepool {
Person *person1=[[Person alloc]init];
person1.name=@"Kenshin";
Account *account1=[[Accountalloc]init];
account1.balance=100000000.0;
person1.account=account1;
account1.balance=200000000.0;//注意執(zhí)行到這一步會觸發(fā)監(jiān)聽器回調(diào)函數(shù)observeValueForKeyPath:ofObject: change: context:
//結(jié)果:keyPath=balance,object=,newValue=200000000.00,context=(null)
}
return 0;
}
在上面的代碼中我們在給人員分配賬戶時給賬戶的balance屬性添加了監(jiān)聽扣癣,并且在監(jiān)聽回調(diào)方法中輸出了監(jiān)聽到的信息,同時在對象銷毀時移除監(jiān)聽憨降,這就構(gòu)成了一個典型的KVO應(yīng)用父虑。
以上就是iOS中,鍵值編碼KVC及鍵值監(jiān)聽KVO的相關(guān)使用方法和步驟授药,希望本文的分享可以幫助大家更好的掌握相關(guān)知識士嚎。
相關(guān)文章:《iOS開發(fā)之UITableViewCell的常用屬性》
文章來源: Martin'sBlog