Swift dealloc
と同等のdeinit
に相当 のようです。ただし、UIViewControllerでメソッドを定義しようとすると、期待どおりに動作しません...
セットアップ
deinit
(Swift)またはdealloc
(Objective-C)にブレークポイントを配置します。VC2では、「閉じる」ボタンのアクションに次の操作を行わせます。
// Swift:
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
// Objective-C:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Objective-C、dealloc
ブレークポイントがヒットする方法に注意してください。
一方、Swiftでは、deinit
ブレークポイントはヒットしません。
deinit
が呼び出されないのはなぜですか?これはバグですか、それとも設計によるものですか?
これが仕様によるものである場合、View Controllerが不要になったときにリソースを解放するためにクリーンアップコードをどこに配置すればよいですか? (このメソッドは廃止されているため、viewDidUnload
に含めることはできません。viewDidDisappear
に含めることはできません。他の何かがその参照を保持している可能性があり、最終的に再び表示されるからです。)
注:Swiftでdealloc
メソッドを定義しようとすると、次のエラーが表示されます。
Objective-Cセレクター 'dealloc'を持つメソッド 'dealloc()'は、同じObjective-Cセレクターを持つdeinitializerと競合します。
Swift View ControllerがObjective-Cコントローラから継承し、Objective-Cのdeallocメソッドにブレークポイントを設定すると、上記で定義したバグのある同じ動作になります:deinit
は呼び出されませんが、dealloc
は呼び出されます。
割り当てを使用してメモリ内のクラスのインスタンスの数を表示しようとすると、両方のバージョンで同じことが表示されます:# Persistent
は常に1で、# Transient
は、2番目のView Controllerを表示するたびに増加します。
上記の設定を考えると、View Controllerを保持する 強参照サイクル はないはずです。
TLDR:
deinit
で機能します。deinit
メソッドに属している必要があります。私を正しい方向に向けてくれたアダム に感謝します。大規模なテストは行いませんでしたが、deinit
でのブレークポイントの動作は、コードの他の場所とは異なるようです。
each行番号にブレークポイントを追加した例をいくつか示します。動作するもの(実行の一時停止、メッセージの記録などのアクションの実行など)は、➤記号で示されます。
通常、メソッドが何もしない場合でも、ブレークポイントは自由にヒットします。
_➤ 1
➤ 2 func doNothing() {
➤ 3
➤ 4 }
5
_
ただし、空白のdeinit
メソッドでは、[〜#〜] no [〜#〜]ブレークポイントがヒットします。
_ 1
2 deinit {
3
4 }
5
_
コードをさらに追加すると、ブレークポイントの後に実行可能なコード行があるかどうかに依存していることがわかります。
_➤ 1
➤ 2 deinit {
➤ 3 //
➤ 4 doNothing()
➤ 5 //
➤ 6 foo = "abc"
7 //
8 }
9
_
特に、7行目と8行目に注意を払ってください。これは、doNothing()
の動作とは大きく異なるためです。
doNothing()
で4行目のブレークポイントがどのように機能するかのこの動作に慣れた場合、この行で5行目(または4行目)にのみブレークポイントがある場合、コードが実行されていないと誤って推測する可能性があります例:
_➤ 1
➤ 2 deinit {
➤ 3 number++
4 // incrementNumber()
5 }
6
_
注:同じ行で実行を一時停止するブレークポイントの場合、作成された順にヒットします。それらの順序をテストするために、ブレークポイントをLog Messageおよびアクションの評価後に自動的に続行に設定します。
注:私のテストでは、別の潜在的な落とし穴もありました。print("test")
を使用すると、デバッグ領域がポップアップしてメッセージが表示されます(メッセージは太字で表示されます)。ただし、ブレークポイントを追加してLog Messageに通知すると、通常のテキストでログに記録され、not デバッグ領域をポップして開きます。出力を表示するには、デバッグ領域を手動で開く必要があります。
注:これはすべてXcode 7.1.1でテストされました
私はまだ試していませんが、あなたのために this を見つけました:
Swiftの最適化段階の一部であるdeinit(奇妙な)内に何らかのコードを配置しない限り、関数は呼び出されないようです。
提案されたとおりにdeinit内にprintステートメントを入れて、結果を報告してください