9

このことを考慮:

id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:MyNotification 
                object:nil 
                 queue:nil 
            usingBlock:^(NSNotification *note) {
                [[NSNotificationCenter defaultCenter] 
                        removeObserver:observer 
                                  name:MyNotification 
                                object:nil
            ];
            // do other stuff here...
    }
];

このパターンを使用して、通知を一度観察してから観察を停止しています。しかし、LLVM は (ARC の下で)ブロックによってキャプチャされたときに変数 'observer' が初期化されていないことを教えてくれます。

ブロックは初期化の前に必ず変数をキャプチャし、初期化子の一部であるため、これを修正するにはどうすればよいですか? __block修飾子 onを使用するとobserverうまくいきますか?

4

3 に答える 3

17

への回答で説明されているように

Observer を NSNotificationCenter:addObserverForName:usingBlock getから削除しないのはなぜですか?

必ず

  • add __block、ブロックが初期化された変数を参照するように、AND
  • を追加__weakして、保持サイクルを回避します。(後者は ARC にのみ適用されます。ARC がないと、ブロックは変数への強い参照を作成しません。)__block

したがって:

__block __weak id observer = [[NSNotificationCenter defaultCenter] ...
于 2013-10-22T20:59:47.083 に答える
0

はい、使用__blockすると問題が解決します。

これがないと、ブロックはブロックの作成時に変数の値のコピーを取得します。(この場合、これは「初期化されていません。」) これにより、ブロックは (本質的に) 変数自体を取得するため、ブロック内から値を変更できます。したがって、外部から行われた変更も「追跡」します。

于 2013-10-22T20:54:53.393 に答える
0

はい、オブザーバーを事前に宣言するとうまくいくと思います__block id observer;

于 2013-10-22T20:52:29.650 に答える