2

プロジェクトをARCを使用するように変換している最中で、特別な問題が発生しました。ネットワークからダウンロードされたファイルのキャッシュを管理するクラスがあります。各ファイルはiPhoneファイルシステムに保存され、関連するオブジェクトはそのマネージャークラスに保持されます。ファイルを使用したい他のオブジェクトは、私のマネージャーにキャッシュオブジェクトを要求し、ファイルが必要な限りそれを保持します。

しかし、時々、マネージャーはキャッシュをクリーンアップし、古いファイルを削除します。もちろん、その時点で使用中のファイルを削除するべきではありません。ARCの前は、関連するオブジェクトのretainCountを使用して次のことを検出しました。

// if retainCount is 1 then only the cache has a reference to it
if( obj.retainCount <= 1 ) {
    [obj deleteFile];
    [cache removeObject:obj];
}

これは完全に機能しました[はい、retainCountの信頼性の欠如に関する警告については知っていますが、私の経験では、retainCount> 1の場合、複数のオブジェクトがそれを保持していることを確認できます]

ただし、ARCでは、retainCountを使用できなくなりました。独自の保持カウントメカニズムを導入し、ファイルを使用するすべてのオブジェクトにファイルオブジェクトを明示的に保持および解放するように要求することができます。しかし、それはエラーが発生しやすく、まさにARCが解決することになっている種類のことです。

同じことを達成するためのより良い方法を知っていますか?

4

3 に答える 3

5

この機能は、とによって最も適切に処理されNSCacheますNSDiscardableContent。これは、明示的なstart呼び出しendを使用して、必ずしも保持する必要のないものへの強力な参照を維持できるようにします(自動的に再作成するため)。これを使用NSCacheすると、一時停止されている場合でも破棄可能なコンテンツを自動的にダンプするなど、他の利点も得られます。のようなものがないとNSCache、余分なキャッシュをダンプするのではなく、メモリが少なくなると殺されてしまいます。

そうは言っても、あなたは別のシステムを構築しました。この特定の問題は、weak参照の目的です。キャッシュは、強い参照ではなく、オブジェクトへの弱い参照を維持する必要があります。デリゲートの非保持配列で説明されているいくつかのアプローチがあります。私は個人的に解決策を好みNSValueます。承認された答えは素晴らしくシンプルに聞こえますが、CFArray正しく使用するには、ARCをよく理解している必要があります。NSValue解決策ははるかにトリッキーではありません。

理想的には、ファイルオブジェクトがキャッシュされていることを知っている場合、ファイルオブジェクトはキャッシュにそれらを削除するように指示できますdealloc。それ以外の場合は、配列から空の値を定期的にクリアできます。

于 2012-03-02T17:39:28.733 に答える
0

オブジェクトの実装にint変数を設定し、オブジェクトが保持されるたびにそれをインクリメントし、deallocメソッドをオーバーライドしてデクリメントするだけです。同じ保持カウントですが、カスタムオブジェクトにのみ有効です。

于 2012-03-02T17:17:55.127 に答える
0

これがあなたのニーズに適用できるかどうかはわかりませんが、連想参照を知っていますか?これらを使用すると、スレーブオブジェクトをマスターオブジェクトにアタッチできるため、マスターが存続する限りスレーブオブジェクトは存続します。これにより、制御できないオブジェクトにオブジェクトをアタッチできるだけでなく、オブジェクトの寿命についても知ることができます。

これを使用して、カスタムクラスオブジェクトをアタッチすることで「obj」を監視できますか。「obj」の割り当てが解除されると、そのカスタムクラスのdeallocが呼び出されます。そのカスタムdeallocで、ファイルの削除を実行できます。

于 2012-11-12T21:32:20.347 に答える