我很难通过键值观察手动触发属性更新。这是一个用来说明我的问题的人为例子:
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:
事件?这种方法不能像我想的那样工作吗?
答案 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"];
}