プロジェクトをARCに切り替えましたが、IBOutletsにstrong
とweak
のどちらを使用する必要があるのかわかりません。 Xcodeはこれを行います。たとえば、インターフェイスビルダーでUILabel
を作成し、アシスタントエディターを使用してViewController
に接続すると、次のようになります。
@property (nonatomic, strong) UILabel *aLabel;
strong
を使用していますが、代わりにRayWenderlich Webサイトで次のようなチュートリアルを読んでいます。
しかし、これら2つの特定のプロパティについては、他の計画があります。
strong
の代わりに、weak
として宣言します。
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
Weak
は、すべてのoutletプロパティに推奨される関係です。これらのビューオブジェクトはすでにビューコントローラのビュー階層の一部であり、他の場所に保持する必要はありません。アウトレットweak
を宣言することの大きな利点は、viewDidUnloadメソッドを記述する時間を節約できることです。現在、
viewDidUnload
は次のようになっています。
- (void)viewDidUnload
{
[super viewDidUnload];
self.tableView = nil;
self.searchBar = nil;
soundEffect = nil;
}
これを次のように簡略化できます。
- (void)viewDidUnload
{
[super viewDidUnload];
soundEffect = nil;
}
したがって、weak
の代わりにstrong
を使用し、videDidUnload
でnilへの設定を削除します。代わりに、Xcodeはstrong
を使用し、viewDidUnload
でself... = nil
を使用します。
私の質問は、いつstrong
を使用する必要があるか、およびweak
はいつですか? iOS 4の展開ターゲットにも使用したいので、unsafe_unretain
を使用する必要があるのはいつですか? ARCでstrong
、weak
、unsafe_unretain
を使用すると、誰でも簡単なチュートリアルで私をうまく説明できますか?
経験則
親が子オブジェクトへの参照を持っている場合、strong
参照を使用する必要があります。子が親オブジェクトへの参照を持っている場合は、weak
参照またはunsafe_unretained
参照を使用する必要があります(前者が使用できない場合)。代表的なシナリオは、デリゲートを扱う場合です。たとえば、UITableViewDelegate
は、テーブルビューを含むコントローラークラスを保持しません。
ここでは、主要な概念を示す簡単なスキーマを示します。
最初のA、B、Cがstrong
参照であるとします。特に、Cにはその親へのstrong
参照があります。 obj1が解放されると(どこか)、A参照は存在しなくなりますが、obj1とobj2の間に循環があるため、リークが発生します。保持カウント(は説明の目的でのみ)と言えば、obj1の保持カウントは2です(obj2にはstrong
への参照がありますit)、obj2の保持カウントは1ですが、obj1が解放されると、その保持カウントは1になり、dealloc
メソッドは呼び出されません。 obj1とobj2はまだメモリに残っていますが、それらへの参照はありません:Leak。
反対に、AとBだけがstrong
refsであり、Cがweak
として修飾されている場合、すべて問題ありません。漏れはありません。実際、obj1がリリースされると、obj2もリリースされます。保持カウントに関して言えば、obj1の保持カウントは1、obj2の保持カウントは1です。obj1が解放されると、その保持カウントは0になり、dealloc
メソッドが呼び出されます。 obj1とobj2がメモリから削除されます。
簡単な提案:ARCを扱うときは、オブジェクトグラフの観点から考え始める
最初の質問については、XIBを扱うときに両方のソリューションが有効です。一般に、weak
参照は、メモリサイクルを処理するときに使用されます。 XIBsファイルに関しては、strong
を使用する場合、nil
をviewDidUnload
に設定する必要があります。そうしないと、メモリ不足の状態で予期しないリークが発生する可能性があるためです。 ARCが代わりに行うので、dealloc
でそれらを解放しません。ターゲットオブジェクトが破棄されると、これらの値は自動的にweak
として設定されるため、nil
はそのような処理を必要としません。ぶら下がりポインタはもうありません。
あなたが興味を持っているなら、私はあなたに本当に読むことを勧めます friday-qa-2012-04-13-nib-memory-management byMike Ash。
2番目の質問について、iOS 4をサポートする必要がある場合は、weak
ではなくunsafe_unretained
を使用する必要があります。
SO内には、多くの質問/回答があります。主なものは次のとおりです。
ARCを使用してiOS 4.0をターゲットとする場合、弱参照をどのように置き換えるのですか?
Objective-Cの自動参照カウントはどのようなリークを防止または最小化しませんか?
ARC、ライフタイム修飾子の割り当て、およびunsafe_unretainedを使用
強い/弱い/保持/ unsafe_unretained /割り当て
お役に立てば幸いです。
更新
Shaunlimのコメントによると、iOS 6のviewDidUnload
メソッドからは非推奨です。ここで私はロブの答えを見ることを本当に提案します: iOS 6-viewDidUnloadがdidReceiveMemoryWarningに移行しますか? 。
IBOutletを介してIB内のオブジェクトに接続されているオブジェクトにウィークを使用できます。この場合、スーパービューが存在する限り、オブジェクトはそこにあるからです。これは、スーパービューにサブビューへの強いポインタがあるためです。
定義しているポインターがオブジェクトへの唯一のポインターである場合、強いものとして宣言する必要があります。
登録済みの開発者の方は、WWDC11とWWDC12のビデオをご覧になることを強くお勧めします。もう1つの優れたリソースは、 Stanford。 のiOS開発ポッドキャストです。