ARC(Automatic Reference Counting) は、強参照をコンパイル時に追跡することでクラスインスタンスのメモリを管理します。コンパイラが retain/release 呼び出しを挿入し、オブジェクトの強参照カウントがゼロに達すると、それは即座に解放されます。バックグラウンドのガベージコレクタによってではなく、決定論的にです。
nil に設定されます。var かつOptionalでなければなりません。unowned(unsafe) ではさらに悪い未定義動作になります)。final class Customer {
var card: Card? // strong: customer owns card
}
final class Card {
unowned let owner: Customer // unowned: card never outlives its owner
init(owner: Customer) { self.owner = owner }
}
習慣ではなく生存期間の関係で選んでください:
| weak | unowned | |
|---|---|---|
| Optional | はい(nilになる) | いいえ |
| ARCコスト | やや高い(追跡される) | 低い |
| 相手のオブジェクトが消えても安全か | はい | クラッシュ |
| 使う場面 | 参照が正当に nilになり得る場合(delegate、先に解放され得る親) | 参照がself より確実に長生きする場合(子 → 必須の親) |
! マーカーが循環を示します。deinit ロギング — 最速のサニティチェックです。画面を閉じたときに deinit が決してプリントされなければ、そのオブジェクトはリークしています。deinit { print("released \(Self.self)") } // silence on dismiss = leak
self をキャプチャするエスケープクロージャ、双方向の親子間の強参照、ターゲットを保持する Timer/DispatchSourceTimer、そして解放されるcancellableに格納されていないCombineの購読などです。
ARCは決定論的なので、リークはGCではなくあなたの責任です。保持されたビューコントローラー1つが、数メガバイトの画像とそのオブジェクトグラフ全体をピン留めしかねません。シニア面接がこれを探るのは、weak と unowned を正しく選び、メモリグラフでリークを証明する方法を知っていることが、長時間動作するアプリの肥大化を防ぐからです。
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する