私はiOS5開発の初心者であり、objective-cを使用しています。 strongとweakストレージの違いを理解するのに苦労しています。私はドキュメントと他のSOの質問を読みましたが、それ以上の洞察はありませんが、それらはすべて私と同じように聞こえます。
ドキュメント:ARCへの移行 -iOS4の保持、割り当て、リリースの条件を参照しています。私を混乱させます。次に、Open U CS193pを調べます。ここでは、強い部分と弱い部分が区別されています。
Strong:「これをポイントしなくなるまでヒープに保持する」
Weak:「他の誰かが強く指し示す限りこれを維持する」
2つの定義は同一ではありません=ポインターがオブジェクトを指していない場合、オブジェクトを保持しているメモリを解放しますか?ポインター、ヒープ、メモリの割り当てまたは割り当て解除の概念は理解していますが、強いものと弱いものの違いは何ですか?
違いは、オブジェクトがstrongへのポインタがなくなるとすぐに割り当てが解除されることです。弱いポインターがそれを指していても、最後の強いポインターがなくなると、オブジェクトの割り当てが解除され、残りの弱いポインターはすべてゼロになります。
おそらく例が整然としています。
私たちのオブジェクトが犬であり、犬が逃げる(割り当て解除される)ことを想像してください。
強いポインターは犬の綱のようなものです。リーシュを犬に取り付けている限り、犬は逃げません。 5人が1本の犬に綱を付けた場合(1つのオブジェクトへの5つの強力なポインター)、5本の綱すべてが切り離されるまで犬は逃げません。
一方、弱いポインターは、小さな子供が犬を指差して、「見て!犬!」と言っているようなものです。犬がひもにつながれている限り、小さな子供たちは犬を見ることができ、彼らはまだそれを指し示します。しかし、すべての綱が外れるとすぐに、犬はそれを何人の小さな子供が指していても逃げます。
最後の強いポインター(リーシュ)がオブジェクトをポイントしなくなるとすぐに、オブジェクトの割り当てが解除され、すべての弱いポインターがゼロになります。
2つの定義は同一ではありません。
絶対違う。あなたが指摘した2つの定義の主な違いは、「他の誰かがいる限り」です。重要なのは「他の誰か」です。
以下を考慮してください。
__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;
これで、<some_object>
への2つのポインターがあります。1つは強いもの、もう1つは弱いものです。 strongObject
をnil
に設定すると、次のようになります。
strongObject = nil;
次に、概説したルールを実行すると、次の質問を自問します。
強い:「これをポイントしなくなるまで、これをヒープに保持する」
strongObject
は<some_object>
を指しません。したがって、それを保持する必要はありません。
弱い:「他の誰かが強く指示している限り、これを維持する」
weakObject
は引き続き<some_object>
を指します。しかし、誰もelseが指し示していないため、この規則は、それを維持する必要がないことも意味します。
その結果、<some_object>
の割り当てが解除され、ランタイムがそれをサポートしている場合(LionおよびiOS 5以降)、weakObject
は自動的にnil
に設定されます。
weakObject
をnil
に設定するとどうなるか考えてみましょう:
weakObject = nil;
次に、概説したルールを実行すると、次の質問を自問します。
強い:「これをポイントしなくなるまで、これをヒープに保持する」
strongObject
は<some_object>
を指します。したがって、それを維持する必要があります。
弱い:「他の誰かが強く指示している限り、これを維持する」
weakObject
は<some_object>
を指していません。
その結果、<some_object>
はnot割り当て解除されますが、weakObject
はnil
ポインターになります。
[<some_object>
が他のどこかの別の強力な参照によって指されていないことを前提としていることに注意してください。
強い
弱い
別の例:学生はObject
であり、すべてのコアコースを終了している限り、卒業できる(deallocate
)と想定されています(strong pointers
)、彼女が彼が彼が彼/彼が任意コースを取ったかどうかに関係なく(weak pointers
)。言い換えると、強いポインターはそのObject
の割り当て解除の唯一の要素です。
いいえ、それらは同一ではありませんが、非常に異なっています。オブジェクトを保持する必要がある場合にのみ、強力を使用します。他のケースではweakを使用します。オブジェクトを保持していないためにオブジェクトがヒープから削除されたかどうかを知ることができるという利点があります。
私はこのパーティーにかなり遅れていることを知っていますが、「強いメモリモデルと弱いメモリモデル」の意味は、ソフトウェアとハードウェアのどちらを話しているかによって異なると指摘して、問題を混同することが重要だと思います。
ハードウェアの場合、弱いまたは強いは、順次一貫性のサポートがあるかどうかを示します。
[SC意味] ...実行の結果は、すべてのプロセッサの動作が何らかの順序で実行された場合と同じであり、個々のプロセッサの動作は、プログラムで指定された順序でこのシーケンスに現れます。 - ランポート、1979
WTFはメモリに関係していますか?異なるプロセッサによる変数への書き込みは、すべてのプロセッサで同じ順序で見られる必要があることを意味します。強力なモデルを備えたハードウェアでは、これは保証されています。弱いモデルのハードウェアでは、そうではありません。
既存の回答は、ソフトウェアメモリモデルの観点からのみ質問を解釈します。ハードウェアはプログラミングとは無関係です。このまさに質問はiOSに言及しており、通常iOSはArm7プロセッサーで実行されます。 Arm7には弱いメモリモデルがあります。強力なモデルを持つプロセッサに慣れているプログラマーにとっては(x86とx64には強力なモデルがあるため私たち全員です)、これはひどいtrapです。強いモデルでは、boolを使用して別のスレッドにシグナルを送信して終了します。フラグをvolatileにマークしない限り、Armの同じコードはまったく機能せず、それでも不安定です。
Arm8 +は、取得/リリースの明示的なサポートによりこれを完全に変更するのは事実ですが、レガシーソフトウェアはこのサポートを使用しません。レガシーソフトウェアには、3つのすべての電話OSと、それらで実行されるすべてのもの、および更新されるまでのコンパイラとライブラリが含まれます。
このトピックをさらに詳しく調べるには、他に類を見ない Herb Sutter を参照してください。