31

strongプロジェクトを ARC に切り替えましたが、IBOutlets を使用する必要があるのかweak​​、IBOutletsを使用する必要があるのか​​ わかりません。Xcode はこれを行います: インターフェイス ビルダーで、UILabelたとえば を作成し、それをアシスタント エディターで に接続するとViewController、次のように作成されます。

@property (nonatomic, strong) UILabel *aLabel;

代わりに、 RayWenderlich strongWeb サイトで次のようなチュートリアルを読みました。

しかし、これら 2 つの特定のプロパティについては、別の計画があります。の代わりに strong、 として宣言しますweak

@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;

Weakは、すべてのアウトレットプロパティに推奨される関係です。これらのビュー オブジェクトは既にビュー コントローラーのビュー階層の一部であり、他の場所に保持する必要はありません。アウトレットを宣言することの大きな利点はweak、viewDidUnload メソッドを記述する時間を節約できることです。

現在、viewDidUnload次のようになっています。

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.tableView = nil;
    self.searchBar = nil;
    soundEffect = nil;
}

次のように簡略化できます。

- (void)viewDidUnload
{
    [super viewDidUnload];
    soundEffect = nil;
}

したがってweak、 の代わりに を使用し、strongでセットを nil に削除します。videDidUnload代わりに、Xcode で を使用しstrong、 で を使用しself... = nilますviewDidUnload

私の質問は次のとおりです。いつstrong、いつ使用する必要がありweakますか? iOS 4 の展開ターゲットにも使用したいので、いつ使用する必要がありunsafe_unretainますか? strongを使用する場合、weakおよびunsafe_unretainARCを使用する場合、誰でも簡単なチュートリアルで私をよく説明するのを手伝ってくれますか?

4

2 に答える 2

69

経験則

親が子オブジェクトへの参照を持っている場合は、参照を使用する必要がありstrongます。子がその親オブジェクトへの参照を持っている場合、weak参照または参照 を使用する必要unsafe_unretainedがあります (前者が使用できない場合)。典型的なシナリオは、デリゲートを扱う場合です。たとえば、 aUITableViewDelegateは、テーブル ビューを含むコントローラー クラスを保持しません。

ここに画像の説明を入力

ここでは、主な概念を示す簡単なスキーマを示します。

最初の A、B、および C がstrong参照であるとします。特に、C にはstrongその親への参照があります。obj1 が (どこかで) 解放されると、A 参照はもう存在しませんが、obj1 と obj2 の間にサイクルがあるため、リークが発生します。保持カウントに関して言えば (説明目的のみ)、obj1 の保持カウントは 2 (obj2 はそれへのstrong参照を持っています) であり、obj2 の保持カウントは 1 です。obj1 が解放されると、その保持カウントは 1 になり、そのdeallocメソッドは呼び出されません。obj1 と obj2 はまだメモリに残っていますが、それらへの参照はありません: Leak

逆に、A と B のみがstrongref であり、C が修飾されている場合weakはすべて問題ありません。漏れはありません。実際、obj1 が解放されると、obj2 も解放されます。保持カウントに関して言えば、obj1 の保持カウントは 1、obj2 の保持カウントは 1 です。obj1 が解放されると、保持カウントは 0 になり、そのdeallocメソッドが呼び出されます。obj1 と obj2 がメモリから削除されます。

簡単な提案: ARC を扱うときは、オブジェクト グラフの観点から考え始めてください。

最初の質問については、XIB を扱う場合、両方の解決策が有効です。一般weakに、参照はメモリ サイクルを扱うときに使用されます。XIBs ファイルに関しては、使用strongする場合は設定する必要がありnilますviewDidUnload。これを行わないと、メモリ不足の状態で予期しないリークが発生する可能性があります。deallocARCがあなたのためにそれをするので、 あなたはそれらを解放しません。代わりに、ターゲット オブジェクトが破棄されると、これらの値が自動的weakに設定されるため、その処理は必要ありません。nilダングリングポインターはもうありません。

興味がある場合は、Mike Ashによるfriday-qa-2012-04-13-nib-memory-managementを読むことを強くお勧めします。

2 番目の質問について、iOS 4 をサポートする必要があるweak場合は、unsafe_unretained.

SO内には多くの質問/回答があります。ここに主なものがあります:

ARC を使用し、iOS 4.0 を対象とする場合、弱参照を置き換えるにはどうすればよいですか?

Objective-C の自動参照カウントが防止または最小化しないのは、どのようなリークですか?

ARC、有効期間修飾子の割り当て、および unsafe_unretained の使用

強い / 弱い / 保持 / unsafe_unretained / 割り当てる

それが役立つことを願っています。

アップデート

shaunlim のコメントによると、iOS 6viewDidUnloadメソッドから開始することは非推奨です。ここで、Rob の回答を参照することを強くお勧めします: iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning? .

于 2012-06-23T14:35:51.100 に答える
11

IBOutlets を介して IB 内のオブジェクトに接続されているオブジェクトには、weak を使用できます。この場合、スーパービューが存在する限りオブジェクトが存在するためです。これは、スーパービューがそのサブビューへの強力なポインターを持っているためです。

定義しているポインターがオブジェクトへの唯一のポインターである場合は、それをストロングとして宣言する必要があります。

開発者として登録されている場合は、WWDC11 と WWDC12 のビデオをご覧になることを強くお勧めします。もう 1 つの優れたリソースは、スタンフォードの iOS 開発ポッドキャストです。

于 2012-06-23T11:08:44.687 に答える