2012-03-15 9 views
1

私はUIViewサブクラスを持っていて、オブジェクトとオブザーバをNSDictionaryに登録しています。removeObserver:forKeyPathが機能していません

このビューを削除すると(ビューを含むビューが削除されたとき)、ビューのdeallocメソッドでremoveObserver:forKeyメソッドが呼び出されます。

ビューオブジェクトが実際にオブザーバから削除されていないため、アプリケーションが後でクラッシュします。私は辞書のobservationInfoを通してこれを確認しました。

私が期待していたとき、私のデアロックが実際に動いているのが分かります。この同じメソッドは、UIButtonUILabelのような他のサブクラス化されたものとうまく動作します。

それが助け場合:他のサブクラス化されたものとの唯一の違いをして、このビューは、他のものは、このビューがコードに組み込まれているNIB、からインスタンス化されている...

これを防ぐかもしれないものすべてのアイデア正しく取り除くことから?

答えて

5

addObserver:forKey:context:を複数回呼び出す可能性があります。通話を正確に調整する必要があります。とremoveObserver:...

addObserver:...はどこに電話していますか?ペン先のオブジェクトがどのようにインスタンス化されているかを認識していますか? addObserver:...awakeFromNibまたはinitWithCoder:に設定することをお勧めします。 nibファイルから作成されたオブジェクトと作成されていないオブジェクトは、しばしばsetupメソッドを使用します。例えば:

- (void)setup { 
    // Do setup work here 
} 

- (id)initWithFrame:(CGRect)frame { 
    self = [super init]; 
    if (self) { 
    [self setup]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)coder { 
    self = [super initWithCoder:coder]; 
    if (self) { 
    [self setup]; 
    } 
    return self; 
} 
+0

私が見たものを見てobservationInfoを使用していたと私はそこに私のオブジェクトのうちの2つを見て覚えていません...私はwillMoveToSuperView' 'の私のセットアップ作業をしていたが、私は「wasn本当にそれが良い場所だと確信していました。 'addObserver:'への私の呼び出しはまだ設定されていないプロパティに依存していたので、私は 'initWithCoder'を使うことができませんでした。あなたの適切な名前の 'setup'にそのセットアップコードを移動することは素晴らしい仕事でした!それはとても簡単な解決策でした。私はそれをやっていないと少しばかげています。どうもありがとうございました。 – hvolmer

+0

この呼び出しを行うもう1つの良い場所は 'awakeFromNib'です。それはすべてのIBOutletが配線された後です。 –