使用KVO观察自定义类的属性

时间:2014-10-24 12:15:45

标签: objective-c key-value-observing

我有2个班级,Foo和Bar,如下所示:

@interface Foo : NSObject
   @property Bar *bar;
@end

@interface Bar: NSObject
   @property int intVal;
   @property long longVal;
@end

现在我想使用KVO来观察类bar对象的属性Foo的变化。但我想知道,如果我更改bar的属性中的一个,intVallongVal,是否有任何通知发送给观察者?

1 个答案:

答案 0 :(得分:3)

您可以使用Foo中的KVO观察bar的值变化,如下所示:

[bar addObserver:self
           forKeyPath:@"intVal"
              options:NSKeyValueObservingOptionNew
              context:nil];

[bar addObserver:self
           forKeyPath:@"longVal"
              options:NSKeyValueObservingOptionNew
              context:nil];

然后你需要实现observeValueForKey方法如下:

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

    if ([keyPath isEqualToString:@"longVal"]) {
    // property longVal changed
    }
    ...
}

编辑:

已经指出的是答案的正确性,所以我会尝试使其更完整:

在Foo中声明一个全局变量:

static void * const MyClassKVOContext = (void*)&MyClassKVOContext;

并在添加观察者时将其作为上下文传递:

[bar addObserver:self
           forKeyPath:@"longVal"
              options:NSKeyValueObservingOptionNew
              context:MyClassKVOContext];

当你观察时完成:

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

        if (context != MyClassKVOContext) {
    [super observeValueForKeyPath:keyPath
                         ofObject:object
                           change:change
                          context:context]; return; }

    if ([keyPath isEqualToString:@"longVal"]) {
    // property longVal changed
    }
    ...
}

这将保证观察环境可能具有的最大唯一性。有关更完整的说明,请参阅评论中的链接答案,因为我仍然认为这超出了本主题的范围。