KVC&KVO&NSNotification

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 在須要的時候 發送通知才調用,且方法自定義

本站公眾號
   歡迎關注本站公眾號,獲取更多信息