0

この問題に関する Apple のドキュメントには、次のように記載されています。

ブロックがコピーされると、ブロック内で使用されるオブジェクト変数への強力な参照が作成されます。メソッドの実装内でブロックを使用する場合:

参照によってインスタンス変数にアクセスすると、self への強い参照が作成されます。

インスタンス変数に値でアクセスすると、変数への強い参照が作成されます。

コード例があります:

dispatch_async(queue, ^{

// instanceVariable is used by reference, a strong reference is made to self

doSomethingWithObject(instanceVariable);

});





id localVariable = instanceVariable;

dispatch_async(queue, ^{

    /*

  localVariable is used by value, a strong reference is made to localVariable

  (and not to self).

*/

doSomethingWithObject(localVariable);

});

しかし、私には意味がありません。インスタンス変数に値でアクセスするにはどうすればよいですか? いつも参照経由でアクセスしていませんか?self.myVariableそれであろうとなかろうとid newName = self.myVariable、それは常に参照によるものです。

次に、この例は、それらが何を意味するのかあまり明確ではありません。最初のケースでは自己保持され、2 番目のケースでは保持されないのはなぜですか? どこでも使用されていないのに、なぜブロックがそれをキャプチャするのでしょうか?

4

1 に答える 1

2

インスタンス変数を使用すると、コンパイラは ivar 名として表示されるものを に変換しself->iVar、それがブロックで使用されます。self->コード内でこれを行うこともできます-先頭に追加して何かにアクセスしてみてください。

編集: したがって、最初のケースでは、 のselfように にアクセスする必要があるため、ブロックは をキャプチャinstanceVariableしますself-> instanceVariable。したがって、ブロックが最終的に実行されるときに、値が何であれ使用されます。selfはオブジェクトなので保持されます。

self-> instanceVariable2 番目のケースでは、一時変数 (オブジェクトであろうとなかろうと) は、その時点での の現在の値が割り当てられます。ブロックが をキャプチャするlocalVariableと、オブジェクトが保持され、dispatch_async 呼び出しの直後に ARC が解放さlocalVariableれるため、保持されるのはブロックだけになりlocalVariableます。それ以降、クラスはインスタンス変数を変更でき、ブロックがキャプチャしたものには影響しません (1 つの例外 - オブジェクトが可変オブジェクトの場合、ブロックは実行時に内容が何であれ使用します - その理由はこの状況では変更可能なオブジェクトを使用するのではなく、変更不可能なコピーを使用してください。

于 2013-06-06T15:46:58.997 に答える