码迷,mamicode.com
首页 > 其他好文 > 详细

KVO

时间:2015-11-16 01:00:18      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:


- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

第一个参数是观察者对象,负责处理监听事件;第二个是观察的属性的路径;第三个是观察的选项;第四个是上下文。

比如说大家都喜欢给宠物取名字,养的猫也会有名字

@interface Cat : NSObject

@property (nonatomic, strong) NSString* name;

@end

我们想要在猫的名字改变的时候有个通知,我们在一个viewcontroller里面做测试,其他多余的代码暂时不要

#import "KVOViewController.h"
#import "Cat.h"

@interface KVOViewController ()

@property (nonatomic, strong) Cat* whiteCat;

@end

@implementation KVOViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _whiteCat = [[Cat alloc] init];
    _whiteCat.name = @"hello";
    
    [_whiteCat addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    
}

- (IBAction)observerTap:(id)sender {
    _whiteCat.name = @"kitty";
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"name"]) {
        NSLog(@"white cat‘s name change");
    }
    
}

@end

我们在当前进行观察的,所以第一个参数观察者是self,当然这不是固定的,可以指到其他地方观察,当都要实现监听方式。

我们是要在猫的名字改变的时候得到事件,所以监听的第二个参数keypath是name。

keypath描述的是要观察的属性,而这个属性,要符合KVC协议的,简单点说,就是这个属性要能够被进行以下操作

- (void)setValue:(id)value forKey:(NSString *)key;

就是说这个属性能够被键值编码,如果我们想观察一个数组的count属性,直接使用

[_obArr addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

程序会crash的,因为数组的count属性不符合键值编码,即简单的不能被setValue:forKey,因为它不是id类型。

keypath,顾名思义,这是一个寻找的路径,所以这里如果是想观察name的属性也是可以用点语法观察的,当然,前提也是要符合KVO协议。

最后一个参数,一般是传nil或者NULL,但作用呢,其实很强大,比如当前有两个Cat的实例,我都要观察他们的name属性变化,我该如何区分是哪个实例呢?就用这个参数,context。我们给上面的例子添加点代码:

@interface KVOViewController ()

@property (nonatomic, strong) Cat* whiteCat;
@property (nonatomic, strong) Cat* blackCat;

@end

@implementation KVOViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _whiteCat = [[Cat alloc] init];
    _whiteCat.name = @"hello";
    
    [_whiteCat addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"White"];
    
    _blackCat = [[Cat alloc] init];
    _blackCat.name = @"kitty";
    
    [_blackCat addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"Black"];
}

- (IBAction)observerTap:(id)sender {
    _whiteCat.name = @"kitty";
    _blackCat.name = @"hello";
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    
    if ([keyPath isEqualToString:@"name"]) {
        
        id instanceObj = (__bridge id)(context);
        NSString* contextStr = instanceObj;
        if ([contextStr isEqualToString:@"White"]) {
            NSLog(@"white cat‘s name change");
        } else if ([contextStr isEqualToString:@"Black"]) {
            NSLog(@"black cat‘s name change");
        }
        
    }
    
}

@end


KVO

标签:

原文地址:http://my.oschina.net/u/574245/blog/530661

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!