一個簡單的KVO例子。atom
兩個界面,第一個界面顯示名字和配偶(spouse)名字,第二個界面顯示修更名字和配偶名字,返回時,將看到第一個界面的名字顯示發生改變。spa
首先定義一個person類做爲model。code
#import <Foundation/Foundation.h> @interface Person : NSObject @property (strong, nonatomic) NSString *name; @property (strong, nonatomic) NSString *address; @property (strong, nonatomic) Person *spouse; + (instancetype)sharedPerson; @end
#import "Person.h" static Person *person = nil; @implementation Person + (instancetype)sharedPerson { if (person == nil) { person = [[Person alloc] init]; person.spouse = [[Person alloc] init]; } return person; } @end
其次構建第一個界面,添加KVO。orm
#import "ViewController.h" #import "Person.h" #define KVO_CONTEXT_NAME_CHANGE @"kvoContextNameChange" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *nameLabel; @property (weak, nonatomic) IBOutlet UILabel *spouseNameLabel; @property (strong, nonatomic) Person *person; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.person = [Person sharedPerson]; [self _watchPersonForChangeName:self.person]; } - (void)_watchPersonForChangeName:(Person *)person { [person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionInitial context:KVO_CONTEXT_NAME_CHANGE]; [person addObserver:self forKeyPath:@"spouse.name" options:NSKeyValueObservingOptionInitial context:KVO_CONTEXT_NAME_CHANGE]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == KVO_CONTEXT_NAME_CHANGE) { self.nameLabel.text = [object valueForKey:@"name"]; self.spouseNameLabel.text = [object valueForKeyPath:@"spouse.name"]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)unwidSegue:(UIStoryboardSegue *)sender { } @end
再次構建第二個界面,經過KVC方式修更名字。server
#import "SecondViewController.h" #import "Person.h" @interface SecondViewController () @property (weak, nonatomic) IBOutlet UITextField *changeNameTextField; @property (weak, nonatomic) IBOutlet UITextField *changeSpouseTextField; @property (strong, nonatomic) Person *person; - (IBAction)changeName:(id)sender; @end @implementation SecondViewController - (void)viewDidLoad { [super viewDidLoad]; self.person = [Person sharedPerson]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (IBAction)changeName:(id)sender { NSString *name = self.changeNameTextField.text; NSString *spouseName = self.changeSpouseTextField.text; [self.person setValue:name forKey:@"name"]; [self.person setValue:spouseName forKeyPath:@"spouse.name"]; NSLog(@"spouse name: %@", self.person.spouse.name); } @end
說明,兩個界面的.h文件裏沒有任何公共接口。界面用storyboard搭建。接口
這個例子很是簡單。還須要對於下面方法進行深刻研究:it
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)contextio