一个简单的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

相关文章
相关标签/搜索