1

根据 Apple 和我看到的大量示例,使用 KVO/KVC 来观察自己是没有问题的。同样根据这些相同的来源,通过在对象的 init 方法中使用 addObserver:forKeypath:options:context: 来设置它不是问题,a 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 on self 在 init 方法中不起作用,但我在文档中没有找到任何可以在这里给我任何提示的内容。

我不知道什么?

4

5 回答 5

4

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

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

如果您正在创建一个类的子类并且要进行初始化,那么您必须覆盖超类的所有指定初始化程序。

NSImageView 设计的初始化器是 -initWithCoder: 和 initWithFrame:。覆盖这两个,而不是初始化。

于 2009-08-17T08:06:50.480 回答
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:...];  
    }  
}
于 2009-08-18T09:01:35.767 回答
0

我不确定是否有这样的限制,但即使你没有,awakeFromNib你也可以通过在你的 init 方法中添加setupObservers到运行循环来创建一个:

[[NSRunLoop currentRunLoop] 
  performSelector:@selector(setupObservers) 
  target:self 
  argument:nil 
  order:1 
  modes:NSDefaultRunLoopMode];
于 2009-08-16T18:59:54.247 回答
0

这是 NSImageView 的子类,所以这里没有任何 'awakeFromNib' 类型的替代方案......

我不明白这一点。您是否在 NIB 中创建此对象?如果一个 NIB 正在创建这个对象,那么它将调用-awakeFromNib. NSLog()您应该确定(使用)的第一件事是您-init是否真的在运行。当什么都没有发生时,通常意味着代码没有运行。

于 2009-08-17T04:37:20.477 回答
0

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

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

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

于 2011-08-27T23:52:53.783 回答