1

Apple と私が見た多くの例によると、KVO/KVC を使用して自分自身を監視することに問題はありません。また、それらの同じ情報源によると、オブジェクトの init メソッドで addObserver:forKeypath:options:context: を使用してこれを設定することは問題ではありません。

- (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メソッドで機能しないようにしますが、ここでヒントを与えるドキュメントには何も見つかりませんでした。

私は何を知りませんか?

4

5 に答える 5

4

問題はおそらく、あなたのケースでは-initが呼び出されないことです。-initWithCoder:は呼び出されます。

すべてのCocoaクラスには、「指定された初期化子」と呼ばれる一連のinitメソッドがあります。各オブジェクトは、インスタンス化されるときに、継承ツリー内の各クラスの指定された初期化子の1つだけを通過することが保証されます。

クラスをサブクラス化していて、初期化を行う必要がある場合は、スーパークラスの指定されたすべての初期化子をオーバーライドする必要があります。

NSImageViewの設計された初期化子は、-initWithCoder:とinitWithFrame:です。initではなく、これら2つをオーバーライドします。

于 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

これはNSImageViewのサブクラスであるため、ここに「awakeFromNib」タイプの代替手段があるわけではありません...

この点がわかりません。このオブジェクトをNIBで作成していますか?NIBがこのオブジェクトを作成している場合、NIBはを呼び出します-awakeFromNibNSLog()(を使用して)最初に確立する必要があるのは、-init実際に実行されているかどうかです。何も起こらない場合は、通常、コードが実行されなかったことを意味します。

于 2009-08-17T04:37:20.477 に答える
0

基本的に、まだ初期化されていないオブジェクトに KVO 通知を追加しようとしています (init 関数は、自己を返す前にオブザーバーを追加します)。次のコードを移動します。

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

- (void)viewDidLoad代わりに。大丈夫です。

于 2011-08-27T23:52:53.783 に答える
0

そのような制限があるかどうかはわかりませんが、ない場合でも、init メソッドの実行ループにawakeFromNib追加することで作成できます。setupObservers

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