IOS 的 KVO機制
概述
Key-Value Observing (簡寫為KVO):當指定的對象的屬性被修改了,允許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察者。 KVO優點
當有屬性改變,KVO會提供自動的訊息通知。這樣的架構有很多好處。首先,開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送訊息通知。這是KVO 機制提供的最大的優點。因為這個方案已經被明確定義,獲得架構級支援,可以方便地採用。開發人員不需要添加任何代碼,不需要設計自己的觀察者模型,直接可 以在工程裡使用。其次,KVO的架構非常的強大,可以很容易的支援多個觀察者觀察同一個屬性,以及相關的值。 執行個體
假設一個情境,電影票的價格顯示在當前螢幕上,當電影票價格更改的時候,即時顯示更新其價格 1、定義DataModel
#import <Foundation/Foundation.h>@interface MovieTicket : NSObject@property (nonatomic, strong) NSString *title;@property (nonatomic, assign) float price;@end#import "MovieTicket.h"@implementation MovieTicket@end
2、viewControl介面
3、viewControl代碼
#import "ViewController.h"#import "MovieTicket.h"NSString *const kChange = @"change";@interface ViewController ()@property (weak, nonatomic) IBOutlet UILabel *titleLab;@property (weak, nonatomic) IBOutlet UILabel *priceLab;@property (nonatomic, strong) MovieTicket *ticket;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; MovieTicket *ticket = [[MovieTicket alloc] init]; ticket.title = @"鋼鐵俠"; ticket.price = 1.99; self.titleLab.text = ticket.title; self.priceLab.text = [NSString stringWithFormat:@"%f", ticket.price]; // 1、 註冊,制定被觀察者的屬性,被觀察者是 ticket,觀察者是當前控制器 // 注意: 對象之間建立串連,而不是兩個類之間 [ticket addObserver:self forKeyPath:kChange options:0 context:NULL]; // 單獨觀察 ticket 的 price 屬性,不需要實現 willChangeValueForKey: 和 didChangeValueForKey:方法 //[ticket addObserver:self forKeyPath:@"price" options:0 context:NULL]; self.ticket = ticket;}- (void)dealloc { // 3、移除觀察 [self.ticket removeObserver:self forKeyPath:kChange];}// 點擊 "改變票價" 類比 改變屬性- (IBAction)changePriceBtnClick:(id)sender { // 將改變屬性的代碼寫在 willChangeValueForKey: 和 didChangeValueForKey: 之間 [self.ticket willChangeValueForKey:kChange]; self.ticket.title = @"美國隊長"; self.ticket.price = arc4random(); [self.ticket didChangeValueForKey:kChange];}// 2、在觀察者中實現回調方法,當被觀察者的監聽的屬性發生改變時調用- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([keyPath isEqualToString:kChange]) { self.titleLab.text = self.ticket.title; self.priceLab.text = [NSString stringWithFormat:@"%f", self.ticket.price]; } if ([keyPath isEqualToString:@"price"]) { }}@end
參考資料
http://www.cnblogs.com/pengyingh/articles/2383629.html