一個簡單的KVO例子

一個簡單的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

相關文章
相關標籤/搜索