KVC,便是指 NSKeyValueCoding,一個非正式的 Protocol,提供一種機制來間接訪問對象的屬性。KVO 就是基於 KVC 實現的關鍵技術之一。架構
一個對象擁有某些屬性。好比說,一個 Person 對象有一個 name 和一個 age 屬性。以 KVC 說法,Person 對象分別有一個 value 對應他的 name 和 address 的 key。 key 只是一個字符串,它對應的值能夠是任意類型的對象。從最基礎的層次上看,KVC 有兩個方法:一個是設置 key 的值,另外一個是獲取 key 的值。以下面的例子:框架
#import "ViewController.h" #import "Person.h" @interface ViewController () @property(nonatomic,strong)Person* p; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.p=[[Person alloc]init]; self.p.father=[[Person alloc]init]; //KVC 演示 [self.p setValue:@"mrzhang" forKey:@"name"]; [self.p setValue:@"laozhang" forKeyPath:@"father.name"]; NSString* name=[self.p valueForKey:@"name"]; NSLog(@"person:name:%@ father name:%@",name,self.p.father.name); }
使用plist 來加載,直接能夠對 對象裏的實例進行賦值或讀取post
Person.hatom
person.plist 文件以下圖spa
NSString* path=[[NSBundle mainBundle] pathForResource:@"person" ofType:@"plist"]; NSArray * arr=[NSArray arrayWithContentsOfFile:path]; //能夠直接取father 屬性 不須要咱們先實例出Father對象 NSLog(@">>>%@", [arr valueForKeyPath:@"father.name"]);
K-V 的形式取值或賦值減少了耦合度,key 與 key path 要區分開來,key 能夠從一個對象中獲取值,而 key path 能夠將多個 key 用點號 「.」 分割鏈接起來設計
KVO:code
當指定的對象的屬性被修改了,容許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察者server
KVO的優勢:
當 有屬性改變,KVO會提供自動的消息通知。這樣的架構有不少好處。首先,開發人員不須要本身去實現這樣的方案:每次屬性改變了就發送消息通知。這是KVO 機制提供的最大的優勢。由於這個方案已經被明肯定義,得到框架級支持,能夠方便地採用。開發人員不須要添加任何代碼,不須要設計本身的觀察者模型,直接可 以在工程裏使用。其次,KVO的架構很是的強大,能夠很容易的支持多個觀察者觀察同一個屬性,以及相關的值。
KVO如何工做:
須要三個步驟來創建一個屬性的觀察員。理解這三個步驟就能夠知道KVO如何設計工做的。 對象
(1)首先,構思一下以下實現KVO是否有必要。好比,一個對象,當另外一個對象的特定屬性改變的時候,須要被通知到。
例 如,A對象但願可以覺察到B對象的age屬性的任何變化。 blog
(2)那麼 A必須發送一個「addObserver:forKeyPath:options:context:」消息,註冊成爲 B屬性的觀察者。(說 明:「addObserver:forKeyPath:options:context:」方法在指定對象實例之間創建了一個鏈接。注意,這個鏈接不是兩 個類之間創建的,而是兩個對象實例之間創建的。)
【被監聽對象 addObserver 監聽者 forKeyPath 被監聽對象的屬性 options監視內容(新值或舊值)context額外信息】;
(3)爲了可以響應消息,觀察者必須實現 「observeValueForKeyPath:ofObject:change:context:」方法。這個方法實現如何響應變化的消息。在這個方 法裏面咱們能夠跟本身的狀況,去實現應對被觀察對象屬性變更的相應邏輯。
(4)假如遵循KVO規則的話,當被觀察的屬性改變的話,方法 「observeValueForKeyPath:ofObject:change:context:」會自動被調用。
須要強調的是KVO的回調要被調用,屬性必須是經過KVC的方法來修改的,若是是調用類的其餘方法來修改屬性,這個觀察者是不會獲得通知的。
NSNotification:
一、監聽通知
【center addObserver :監聽者 selector:須執行的方法 name:所監聽者通知的名稱 object:通知發送者】;
二、通知中心發佈消息
【center PostNotificationName:@「test」object:@"11"】;
for example:
- (void)viewDidLoad { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test:) name:@"testNotice" object:@"test"]; [[NSNotificationCenter defaultCenter]postNotificationName:@"testNotice" object:@"test"]; } -(void)test:(NSNotification*)noti{ NSLog(@"name:%@,object:%@",noti.name,noti.object); }
總結:KVO與NSNotification
相同點:均可以經過addObserver 方法來監聽,都是能經過監聽得到處理
不一樣點:觸發點不同 KVO在屬性上經過 K-V 發生改變時,自動調用observeValueForKeyPath方法
而NSNotification 在須要的時候 發送通知才調用,且方法自定義