2012-09-11 10 views
5

私はブロック内で自己を参照し、保持サイクルを作成しないで頭がおかしくなります。ブロック、自己、保持サイクル

あなたは私の理解が正しければ、私が知っていることができます:私が今までブロック内の自己を参照する場合、それは保持サイクルを作成します

、代わりに私がブロックの外で自己への弱参照を作成する必要がありますブロック内の弱い参照を使用していますか?

ありがとうございます!

答えて

11

はい、それは少数の例外を除いて、正しい:selfは例えば、間接ブロックを保持してしまう場合にのみ発生

Aサイクルを保持しますコースの場合を除き

dispatch_async(dispatch_get_main_queue(), ^{ [self dosomething]; }); // Safe, dispatch_async will not be retained by you 

selfmypropertyのプロパティのプロパティmyblockを設定する:このようなディスパッチコード、のようなもののためにブロックを使用した場合

self.myproperty.myblock = ^{ [self dosomething]; }; // ERROR: Retain Cycle 

はしかし、保持サイクルは、(通常は)発生しません。保持サイクルの基準を持つブロックの中で、dispatch_async関数を呼び出します。

これは本当に混乱していて、私はそれが修正されることを願っています。さて、私自身の意見を:


それは前ARCのコードでは、これは問題ではありませんでしたが、ブロックは自動的に、彼らはキャプチャする任意のオブジェクトを保持しているので、それは問題だ、必ずしもそうではありませんでした。

selfのタイプをinstancetype constの代わりに__weak instancetype constにすることで、これは非常に簡単な修正ですので、これが修正されることを希望します。 ARCでクラスクラスタを作成する際のいくつかの問題も解決しますが、これは問題の中で最大のものではありませんが、まだ存在します。

サイクルを保持する利点は、それほど多くありません。

+1

保持サイクルは厳密にエラーではありません。ブロックの所有者が、ブロックを破棄してサイクルを壊して問題を回避する前にブロックを廃棄することはよくあります。 –

+0

自己への弱い参照を作成してブロック内の弱い参照を使用するのは安全ですか?保持サイクルがないことを確認するだけですか? (ブロックが実行されるときにselfWeakが無意味なポインタになる可能性があると私は大丈夫だと仮定します) –

+0

@WiseShepherdもちろん、これはほとんどの状況でサイクルを保持する方法です。 –

関連する問題