使用KVO触发属性更新

时间:2011-08-09 09:01:34

标签: cocoa key-value-observing

我很难通过键值观察手动触发属性更新。这是一个用来说明我的问题的人为例子:

Bar.h

#import <Foundation/Foundation.h>

@interface Bar : NSObject
{
    NSString *test;
}

@property (nonatomic, retain) NSString *test;

-(void) updateTest1;
-(void) updateTest2;

@end

Bar.m

#import "Bar.h"

@implementation Bar

@synthesize test;

-(id) init
{
    if (self = [super init])
    {
        self.test = @"initial";
    }
    return self;
}

-(void) updateTest1
{
    self.test = @"updating 1";
}

-(void) updateTest2
{
    NSString *updateString = @"updating 2";
    [updateString retain];
    test = updateString;
    [self didChangeValueForKey:@"test"];
}

@end

foo.h中

#import <Foundation/Foundation.h>

@interface Foo : NSObject

@end

Foo.m

#import "Foo.h"

@implementation Foo

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"something changed!");
}

@end

的main.m

#import <Foundation/Foundation.h>
#import "Foo.h"
#import "Bar.h"

int main (int argc, const char * argv[])
{

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Bar *bar = [Bar new];
    Foo *foo = [Foo new];

    [bar addObserver:foo forKeyPath:@"test" options:0 context:nil];

    [bar updateTest1];
    [bar updateTest2];

    [pool drain];
    return 0;
}

程序返回:

2011-08-09 03:57:52.630 Temp[5159:707] something changed!
Program ended with exit code: 0

为什么didChangeValueForKey:不会触发观察者的observeValueForKeyPath:ofObject:change:context:事件?这种方法不能像我想的那样工作吗?

2 个答案:

答案 0 :(得分:6)

由于您忘记了相应的

,因此未触发通知
[self willChangeValueForKey:@"test"];

必须始终与didChangeValueForKey:

配对

答案 1 :(得分:1)

NSKeyValueObservingOptions

这些常量传递给addObserver:forKeyPath:options:context:并确定作为传递给observeValueForKeyPath的更改字典的一部分返回的值:ofObject:change:context:。 如果您不需要更改字典值,则可以传递0。

enum {

NSKeyValueObservingOptionNew = 0x01,

NSKeyValueObservingOptionOld = 0x02,

NSKeyValueObservingOptionInitial = 0x04,

NSKeyValueObservingOptionPrior = 0x08

}; typedef NSUInteger NSKeyValueObservingOptions;

试试这个

[bar addObserver:foo forKeyPath:@"test" options:NSKeyValueObservingOptionNew context:nil];

更改此代码

-(void) updateTest2
{
    NSString *updateString = @"updating 2";
    [updateString retain];
    test = updateString;
    [self didChangeValueForKey:@"test"];
}

-(void) updateTest2
{


    self.test = @"updating 2"//note here

    [self didChangeValueForKey:@"test"];
}