3

決定論的なdealloc(例:クリーンアップ用)に依存することは正当な慣行ですか?

ARC、および手動の参照カウントでさえ本質的に決定論的であるため、他の人がすぐに呼び出されるdeallocに依存することについてどう考えているのか疑問に思いました(比較的、autoreleasepoolを考慮して)。

C#のような他の最新のプログラミング言語では、決定論的なクリーンアップが必要な場合に、disposeのようなパターンが採用されます。そして、ガベージコレクションを備えたObj-Cもこの動作を促進すると思います。

つまり、例としては、viewDidDisappearのときどきイライラするセマンティクスをプログラムしようとするのではなく、deallocの未処理の操作をキャンセルするUIViewControllerがあります。

もう1つの例は、openまたはcloseを呼び出す必要はなく、initとdeallocでそれぞれ暗黙的に開いたり閉じたりするストリームオブジェクトです。

AppleはGCを廃止したので、この種のパターンはすぐには壊れないだろうと思います。これを奨励すべきかどうかについてのドキュメントは見つかりませんが、非常に便利です。

4

2 に答える 2

2

あなたは絶対に正しいです、あなたは最後の参照がリリースされた後比較的すぐに呼び出されることに頼ることができますdealloc(手動でまたはARCを通して、それは重要ではありません)。システムに空き時間がある場合、または場合によっては呼び出されないときにファイナライザーが呼び出されるGCとは異なり、dealloc非常に確実に呼び出されます。Appleは、内部ですべてのリソースクリーンアップタスクを実行する必要があることを提案することにより、このパターンの使用を許可し、さらには推奨していますdealloc

deallocただし、これは、排他的に依存する必要があるという意味ではありません。たとえば、NSStreamクラスを見てみましょう。このクラスは明示的なcloseメソッドを提供し、の呼び出しが発生するのを待たずに、ストリームを自由に強制的に閉じることができますdealloc。これは、リソースが非常に高価な場合(ファイルハンドル、セマフォなど)に従うのに非常に適したパターンです。これらのリソースを解放するための主要なメカニズムは、別のclose方法である必要があります。このdeallocメソッドはリソースも解放する必要がありますが、の呼び出しを逃したことを通知する警告も発行する必要がありますclose

于 2012-11-30T02:57:35.817 に答える
1

メモリ管理システムに関係なく、高価なリソース(ファイルとソケット、イメージ、ビュー、大容量のメモリ割り当てなど)をオブジェクトの存続期間に結び付けるのは危険です。手動で保持および解放している場合でも、無意識のうちにオブジェクトをどこかに保持して忘れてしまう可能性があります(または、リリースを不必要に遅らせる必要があります)。ARCは、保持がどこから来ているのか、対応するリリースがいつ有効になるのかがはるかに明確でないため、これらのことが発生する可能性がさらに高くなります。そしてもちろん、GCはそれをすべて完全に無期限にします。

一般に、高価なリソースや限られたリソースの場合は、個人事業主のパターンに従うようにしてください。はい、それでも通常どおり保持/解放して、時期尚早の割り当て解除を防ぐことができますが、支配的な所有者は明確に定義され、完了時にオブジェクトをクリアする責任があります-たとえば、invalidate、close、または適切なものを呼び出します。これは、多くの一般的なケースで完全に理にかなっています。たとえば、ファイルやソケットを使い終わったときは一般的にわかっているので、ラッパークラス内にカプセル化されている場合でも、明示的に閉じる必要があります。

場合によっては、これは、他の方法では隠されたままになる、または追跡するのが難しいバグを見つけるのにも役立ちます。たとえば、ファイルが閉じられた後に読み取りまたは書き込みが呼び出されたときにファイルラッパークラスが例外を発生させた場合、すぐにそれらのケースをキャッチします。一方、ファイルが終了したと思ったときにファイルを閉じなかった場合、読み取りと書き込みは通常どおりに行われ、ファイルに予期しないデータが含まれていることに気付かない可能性があります。

同じ原則を使用して、保持サイクルを中断することもできます。

于 2012-11-30T07:19:36.693 に答える