首页 > 代码库 > 一个简单的KVO例子

一个简单的KVO例子

一个简单的KVO例子。

两个界面,第一个界面显示名字和配偶(spouse)名字,第二个界面显示修改名字和配偶名字,返回时,将看到第一个界面的名字显示发生改变。

首先定义一个person类作为model。

#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。

#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方式修改名字。

#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搭建。

这个例子非常简单。还需要对于下面方法进行深入研究:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context



一个简单的KVO例子