iOS5の強力なストレージと弱いストレージの説明


114

私はiOS5開発が初めてで、objective-cを使用しています。強力なストレージと弱いストレージの違いを理解できません。ドキュメントと他のSOの質問を読みましたが、それらはすべて私と同じように聞こえ、それ以上の洞察はありません。

はドキュメントを読みます:ARCへの移行 -iOS4の保持、割り当て、およびリリースの用語を参照しています。これは私を混乱させます。次に、Open U CS193pを調べます。OpenとCS193pは、強弱を区別します。

:「これ以上指さないようになるまでヒープ内に保持する」
:「他の誰かが強く指さしている限り、これを保持する」

2つの定義は同じではありませんか?ポインターがオブジェクトを指していない場合、オブジェクトを保持しているメモリを解放しますか?ポインタ、ヒープ、メモリの割り当てまたは割り当て解除の概念を理解していますが、強いと弱いの違いは何ですか?


ARCを使用している場合でも、メモリ管理モデルは引き続き適切です。参照カウントを理解する必要がありますが、手動で行う必要はありません。したがって、最後の段落は不当な要求です。
jrturton 2012

回答:


509

違いは、オブジェクトへの強力なポインタがなくなるとすぐにオブジェクトの割り当てが解除されることです。弱いポインターがそれを指している場合でも、最後の強いポインターがなくなると、オブジェクトは割り当て解除され、残りのすべての弱いポインターはゼロにリセットされます。

おそらく例が正しいでしょう。

オブジェクトが犬であり、犬が逃げ出したい(割り当てを解除したい)と想像してください。

強いポインタは、犬の首輪のようなものです。あなたが犬に紐を取り付けている限り、犬は逃げることはありません。5人が1本の犬にリーシュを取り付けた場合(1つのオブジェクトへの5つの強力なポインタ)、5つのすべてのリーシュが外れるまで犬は逃げません。

一方、弱いポ​​インタは、犬を指して「見て!犬!」と言う小さな子供たちのようなものです。犬がまだひもにつながっている限り、小さな子供たちは犬を見ることができます。しかし、すべての鎖が外れるとすぐに、いくつ小さな子供が指を指していても、犬は逃げます。

最後の強いポインター(リーシュ)がオブジェクトを指さなくなるとすぐに、オブジェクトは割り当て解除され、すべての弱いポインターはゼロにリセットされます。


2
これは、AppleのMalcom Crawfordが数年前に発表したアナロジーに基づいています。彼はそれをどこで手に入れたのか分からない。
BJホーマー

本で似たようなもの(前編)を読んだことを覚えていますが、それはヒレガスだったと思いますが、彼はどこかからそれを手に入れることができたでしょう...それは良いものです!
jrturton 2012

14
+1の良い例。これは、リーシュが保持/解放される方法に関するヒレガスの例の派生物ですが、私はこの強弱の適応が大好きです。
Dave DeLong、2012

2
@DaveDeLong:まあ、ARCの10.6では違法です。まったく使えません。だからそれはちょっと無関係なポイントです。
BJホーマー

5
もう1つの良いものはヘリウム風船です。少なくとも1つの紐が保持されている限り、それは浮きません。ひも/バルーンの類似は、「所有権」が保持/解放によって管理されることを人々に忘れさせるのにも優れています。
スティーブウェラー

34

2つの定義は同じではありません。

絶対違う。あなたが指摘した2つの定義の主な違いは、「他の誰かと同じくらい」です。重要なのは「他の誰か」です。

以下を検討してください。

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

これで、への2つのポインタが得られました。1 <some_object>つは強い、もう1つは弱いです。そのように設定strongObjectした場合nil

strongObject = nil;

次に、概説したルールを実行すると、次の質問を自問することになります。

  1. 強力:「これ以上指さなくなるまで、これをヒープ内に保持してください」

    strongObject<some_object>これ以上は指しません。したがって、それを保持する必要はありません。

  2. 弱点:「他の誰かが強く指摘している限り、これを維持する」

    weakObjectまだを指してい<some_object>ます。しかし、他の誰もそれを指さないので、このルールはそれを維持する必要がないことも意味します。

その結果、<some_object>割り当てが解除され、ランタイムがサポートしている場合(LionおよびiOS 5以降)、weakObject自動的にに設定されnilます。

次に、そのように設定weakObjectした場合にどうなるかを考えますnil

weakObject = nil;

次に、概説したルールを実行すると、次の質問を自問することになります。

  1. 強力:「これ以上指さなくなるまで、これをヒープ内に保持してください」

    strongObjectを指し<some_object>ます。したがって、それを保持する必要があります。

  2. 弱点:「他の誰かが強く指摘している限り、これを維持する」

    weakObjectを指さない<some_object>

結果は、ある<some_object>されていない割り当て解除、しかしweakObjectだろうnilポインタ。

[想定しているすべてのことは<some_object>、別の場所の別の強力な参照/「保持」される他の手段によって指されていないことに注意してください]


1
したがって、強いと弱いの主な違いは、強くポイントされているオブジェクトの割り当て解除では、関連するすべての弱いポインターが自動的にnil-outされることです。そして、弱いポインタが何かを指すには、常に強いポインタが存在します。もしそうなら、メインのアプリケーションオブジェクトを強く指す必要がありますか?
KMC

弱いポインタが有効なものを指すようにするには、はい、強いポインタが必要です。それに加えて、iOS 5とLionは弱い参照のオートニリングをサポートしており、あなたが言うことを理解できるという事実に加えて。iOS 4のランタイムはそれをサポートしていませ。「メインアプリケーションオブジェクト」私はあなたがUIApplicationオブジェクトを意味すると思いますか?それはの内部の仕組みによって強く参照されUIKitます-しかし、あなたはそれについて心配する必要はありません。
mattjgalloway

「strongObject」の代わりに「strongObjectPointer」のような言葉が使えると思います。だから、プログラミングの初心者はより良い意味を持つでしょう。@BJホーマーの投稿Mr.Matt.Interesting :)のいいキャッチ
Vijay-Apple-Dev.blogspot.com

2

強い

  1. プロパティと割り当てられた値の間に所有権を作成します。
  2. これはARCのオブジェクトプロパティのデフォルトであるため、参照カウントについて心配する必要がなく、参照を自動的に解放します。
  3. 保存用の交換品です。保持として使用する必要がある場合にのみ使用します。

弱い

  1. プロパティと割り当てられた値の間に非所有権を作成します。
  2. 親オブジェクトで強いが使用され、親が解放されると子オブジェクトで弱いが使用され、子オブジェクトの参照もnilに設定されます。
  3. 保持サイクルの防止に役立ちます。
  4. ガベージコレクターによるコレクション時に、参照先オブジェクトを保護しません。
  5. 弱いは本質的に割り当てられた、保持されないプロパティです。

ここで、保持サイクルが通常何であるかについて言及する価値があります。Aは、オブジェクトBとオブジェクトBへの強い参照が他のオブジェクトAのNothingに強い参照がオブジェクトAまたはBへの強い参照を持っている持っているオブジェクトAとオブジェクトBのオブジェクト:我々は、2つのオブジェクト持っ
ボロ

2

別の例:StudentはでありObject、optional-courses()を取得しているかどうかに関係なく、deallocateすべてのcore-courses(strong pointers)を終了している限り、卒業することができます(weak pointers)。言い換えると、強いポインタがその割り当てを解除する唯一の要因ですObject


1

いいえ、それらは同一ではありませんが、大きく異なります。オブジェクトを保持する必要がある場合のみ、strongを使用します。他のケースではウィークを使用しますが、デメリットとして、オブジェクトを保持していないためにオブジェクトがヒープから削除されたかどうかを知ることができます。


1

私はこのパーティーに遅れていることを知っていますが、「強力で弱いメモリモデル」の意味は、ソフトウェアとハ​​ードウェアのどちらで話しているかによって異なることを指摘して、問題を混乱させることが重要だと思います。

ハードウェアの場合、弱いまたは強いは、順次整合性のサポートがあるかどうかを示します。

[SCは] ...すべてのプロセッサの操作が特定の順序で実行された場合と同じ結果になり、各プロセッサの操作は、プログラムで指定された順序でこの順序で表示されます。- ランポート、1979

WTFはメモリと関係がありますか?異なるプロセッサによる変数への書き込みは、すべてのプロセッサで同じ順序で確認する必要があることを意味します。強力なモデルのハードウェアでは、これは保証されています。弱いモデルのハードウェアでは、そうではありません。

既存の回答は、ソフトウェアメモリモデルの観点からのみ質問を解釈します。ハードウェアはプログラミングには関係ありません。この質問自体は、通常Arm7プロセッサで実行されるiOSについて言及しています。Arm7には弱いメモリモデルがあります。強力なモデルのプロセッサに慣れているプログラマにとって-これはx86とx64が強力なモデルを持っているので私たち全員です-これはひどい罠です。強力なモデルでは、ブール値を使用して別のスレッドに終了を通知することで問題なく動作します。フラグを揮発性としてマークしない限り、Armの同じコードはまったく機能せず、それでも不安定になります。

Arm8 +が取得/解放を明示的にサポートすることでこれを完全に変更することは事実ですが、レガシーソフトウェアはこのサポートを使用しません。レガシーソフトウェアには、3つすべての電話OSとそれらで実行されるすべてのものが含まれ、更新されるまでコンパイラとライブラリも含まれます。

このトピックの詳細な調査については、他に類を見ないハーブサッターを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.