0

私が次のtypedefを持っていると仮定しましょう:

typedef void (^myBlock)(id);

そして、 myBlockを引数として受け入れ、それにいくつかのid変数を生成するメソッドmyMethodがあります。

void myMethod(id myObj, myBlock block) {
    // ...
    block(myObj);
    // ...
}

だから私が次のものを持っている場合:

- (void) someMethod {
    __block id myObj; // Some initialization local to the scope of someMethod;
    // myObj = ... some assignment to myObj so it is not nil...

    dispatch_async(someQueue(), ^{
        // (*) Some long, possibly multi-queued and multi-blocked, processing, 
        // so we are sure that someMethod will run out:
        // ...

        // 1. Can I be sure that myObj is still alive and actual here 
        // after the long processing (*)?

        myMethod(myObj, ^(id myObj) {
            // (**) Some long, possibly multi-queued, processing here too...

            // 2. Can I be sure that myObj is still alive and actual here 
            // after the long processing (**) finishes?
        })
    })
}

myObjを特別に保持して、異なるキュー/ブロックにまたがって存在するようにする必要がありますか?

明白で十分に文書化されたものを求めている場合は申し訳ありません-ARCがデフォルトである可能性が高いときにObjective-Cを学び始めたばかりなので、これらの保持カウント、自動リリース、その他のものについてあまり気にする必要はありません、そして、私がここで説明したような状況でのみそれらについて考えてください。

4

2 に答える 2

1
  1. 長い処理(*)の後、myObjがまだ生きていて、実際にここにあることを確認できますか?

はい。通常、ブロック内の自由変数は、コピー時にブロックによって保持されます。ただし、これは__block変数です。ARCでは、__block変数もブロックによって保持されます(ただし、MRCではそうではありません)。

  1. 長い処理(**)が終了した後、myObjがまだ生きていて、実際にここにあることを確認できますか?

この質問は、変数をキャプチャするブロックとはまったく関係ありません。ここにmyObj、周囲のスコープからキャプチャされていないパラメータ、つまりローカル変数があります。したがって、問題は、ブロックが呼び出されたときに引数が有効なオブジェクトを指しているかどうかということです。引数を取得した引数myMethod()と同期して呼び出すだけなので、ARCでは、呼び出されたとき(つまり、外側のブロックで)引数が有効であると仮定しても問題はありません。上記(1)から有効であることに同意したので、これは真実です。blockmyObjmyMethodmyObj

于 2012-12-16T21:54:09.917 に答える
1
  1. 長い処理(*)の後、myObjがまだ生きていて、実際にここにあることを確認できますか?

はい。ブロック内のブロックがブロック指定子を保持しているため、ブロック指定子を使用していなくても。

  1. 長い処理(**)が終了した後、myObjがまだ生きていて、実際にここにあることを確認できますか?

はい。ブロック内で使用されるすべての変数は、ARCによって保持されます。

PS:これはすべてARCで。

于 2012-12-16T12:58:53.317 に答える