我在我的应用中遇到问题。为方便起见,我的应用代表更容易观察自己的属性。但是,当以观察者身份移除app委托时,我收到错误。
我已将其归结为一个小代码示例和结果(稍后显示)。
我的问题是,什么时候删除自己作为我自己的密钥的观察者是非法的,以及典型的可可开发人员如何在下面的示例中解决问题:
来自此代码...
#import "AppDelegate.h"
@interface Thing : NSObject
@property (nonatomic, strong) Thing * next;
@property (nonatomic, strong) id value;
@end
@implementation Thing
@synthesize next,value;
+(Thing*)thing
{
return [[Thing new] autorelease];
}
@end
@interface AppDelegate ()
@property (strong, nonatomic) Thing * thing;
@end
@implementation AppDelegate
@synthesize window = _window, thing;
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
Thing * thing2 = [Thing thing];
thing2.value = @"hello";
Thing * thing1 = [Thing thing];
thing1.next = thing2;
self.thing = thing1;
[self addObserver:self forKeyPath:@"thing.next.value" options:0 context:NULL];
[self addObserver:self forKeyPath:@"thing.next" options:0 context:NULL];
Thing * thing3 = [Thing thing];
thing3.value = @"goodbye";
self.thing.next = thing3;
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"value did change for keyPath '%@'", keyPath);
[self removeObserver:self forKeyPath:@"thing.next.value"];
[self removeObserver:self forKeyPath:@"thing.next"];
}
@end
我得到了这个结果......
2011-11-03 13:32:02.123 TestKVO [11637:707]的价值确实发生了变化 keyPath'thing.next'
2011-11-03 13:32:02.124 TestKVO [11637:707]无法删除观察者 < NSKeyValueObservance 0x103828250>来自的关键路径“next.value” < Thing 0x10381d970>,很可能是因为键“next”的值 在没有发送适当的KVO通知的情况下已更改。校验 事物类的KVO合规性。
答案 0 :(得分:4)
我认为问题在于您注册了两个包含通知的来源。
相反,你应该:
@"thing.next"
@"thing.next.value"
旧@"thing.next"
值(在change
字典中找到),然后在新{@"thing.next.value"
上注册@"thing.next"
{1}}值(也可在change
词典中找到)。这样,当@"thing.next"
密钥路径发生变化时,绑定保持一致。
答案 1 :(得分:2)
夫妻俩:
1)你实施自己的二传手吗?如果是这样,您需要通过恰当地发送willChangeValueForKey:
和didChangeValueForKey:
来确保它们符合KVO。在Apple的Key-Value Observing Programming Guide中查找有关KVO合规性的部分。
willChange...
和didChange...
。
2)而不是让你的对象观察它自己的属性(有点奇怪的恕我直言),你可以实现自定义的setter,当值发生变化时,它会在对象中做任何你想做的事。