使用addObserver的奇怪问题:forKeypath:options:context:在init方法中

时间:2009-08-16 18:20:59

标签: cocoa cocoa-bindings

根据Apple和我见过的众多例子,使用KVO / KVC观察自己是没有问题的。同样根据相同的来源,通过使用addObserver来设置它不是一个问题:forKeypath:options:context:在对象的init方法中,la:

- (id)init
{
    self = [super init];
    if (self) {
    [self addObserver:self
               forKeyPath:@"selected"
                  options:NSKeyValueObservingOptionNew
                  context:NULL];
    }
    return self;
}

不幸的是,出于某种原因,当我在那里执行时,我的观察者方法不会被调用。如果我将addObserver调用移动到另一个方法,然后在调用方法中调用该方法:

MyObject *newObj = [[MyObject alloc] init];
[newObj setupObservers];

然后一切都很好。这是NSImageView的子类,所以它不像在这里有任何'awakeFromNib'类型的替代品......我真的在这里摸不着头脑,我确信我错过了一些显而易见的东西 - 就像关于事情的规则一样导致自我的KVO无法在init方法中工作,但我没有在文档中找到任何可以给我任何提示的内容。

我不知道什么?

5 个答案:

答案 0 :(得分:4)

问题可能是 - 在你的情况下没有调用-init,-initWithCoder:is。

每个Cocoa类都有一组称为“指定初始值设定项”的init方法。每个对象在被实例化时,都保证在其继承树中通过每个类的一个且只有一个指定的初始值设定项。

如果您正在为一个类创建子类并进行初始化,则必须覆盖超类的所有指定初始值设定项。

NSImageView的设计初始值设定项是-initWithCoder:和initWithFrame:。覆盖这两个,而不是init。

答案 1 :(得分:2)

对于上下文指针,首选方法是:

static void *MyPrivateObservationContext = (void*)@"MyPrivateObservationContext"; // we assume MyPrivateObservationContext is a unique name, I use something of the form ClassNamePropertyObservationContext

然后

-[obj add....... context:&MyPrivateObservationContext];

然后在

-(void)observeValueForKeyPath:....context:c;  
{  
    if (c == &MyPrivateObservationContext) {  
        // do work  
    } else {  
        [super observeValueForKeyPath:...];  
    }  
}

答案 2 :(得分:0)

我不确定是否存在此类限制,但即使您没有awakeFromNib,也可以通过在init方法中将setupObservers添加到运行循环来创建一个[[NSRunLoop currentRunLoop] performSelector:@selector(setupObservers) target:self argument:nil order:1 modes:NSDefaultRunLoopMode];

{{1}}

答案 3 :(得分:0)

  

这是NSImageView的子类,所以   它不像有任何东西   'awakeFromNib'式替代品   这里...

我不明白这一点。你是否在NIB中创建这个对象?如果NIB正在创建此对象,则它将调用-awakeFromNib。您应该建立的第一件事(使用NSLog())是您的-init是否实际运行。当没有任何反应时,通常意味着代码没有运行。

答案 4 :(得分:0)

基本上,您正在尝试将KVO通知添加到尚未初始化的对象(您的init函数在返回self之前添加观察者)。移动以下代码:

[self addObserver:self
       forKeyPath:@"selected"
          options:NSKeyValueObservingOptionNew
          context:NULL];

改为- (void)viewDidLoad。它会没事的。