2012/05/07

NSCacheとNSDiscardableContentについて

データをキャッシュするときに便利そうなNSCacheとNSDiscardableContentについて調べたので簡単にまとめました。

NSCacheの特徴

まず、簡単にNSCacheの特徴を述べます。スレッドセーフでお手軽なNSDictionary、ただし要素列挙やカウント機能なしといったところでしょうか。

  • NSDictionaryのようにkey-value形式でオブジェクトにアクセスできる
  • スレッドセーフであり、ロック不要で別スレッドから追加、削除、クエリができる
  • メモリ警告時に自動でオブジェクトをキャッシュから削除する
  • countLimitとtotalCostLimitという2つの上限値でキャッシュサイズの調節できる

NSCacheでの削除について

NSCacheのキャッシュオブジェクトの削除のタイミングや動作は次のようになっているようです。

  • countLimitまたはtotalCostLimitを超えたときには、オブジェクトがキャッシュから削除される。
    • 不要なものから優先的に削除される (挙動的にはLRUっぽい)
    • 上限を超えたとしても必ず、即座にキャッシュから削除されるわけではない
    • メモリ警告時にもオブジェクトをキャッシュから削除する
  • キャッシュから削除されるときは、オブジェクトが開放可能であるなら実際にdeallocもされる。
  • キャッシュからオブジェクトが削除される直前に、cache:willEvictObjectが呼ばれる (delegateを設定時)。

NSDiscardableContentプロトコルの実装オブジェクトを利用したとき

NSDiscardableContentプロトコルで実装すべきものは、簡単に言えばretainCountとは別の共有カウントを持たせることです (beginContentAccessでカウントアップ、endContentAccessでカウントダウン、など)。

これを実装したオブジェクトをNSCacheに入れると便利らしいです。 NSCacheクラスリファレンスによると、次のように書かれています。

NSCacheに入れる一般的なデータ型は、NSDiscardableContentプロトコルを実装したオブジェクトである。 これを用いたオブジェクトは、利用しなくなったときにコンテンツを取り去ることができ、結果的にメモリが節約できるという利点がある。 デフォルトではキャッシュ内のNSDiscardableContentオブジェクトは、 コンテンツが取り去られているときには自動的にキャッシュから外される (自動削除しない設定にすることも可能)。 また、NSDiscardableContentオブジェクトがキャッシュから外されるときには キャッシュはdiscardContentIfPossibleを呼び出す。

一見便利そうに思えたのですが、挙動を調べてみると、

  • NSCacheはNSDiscardableContentのカウントの増減には関与しない
  • NSCacheがオブジェクトを削除するときはNSDiscardableContentのカウントを気にしない

という感じで、個人的には使い道がよくわかりませんでした。

ちなみに、NSCacheはevictsObjectsWithDiscardedContentがYESであるとき (デフォルトの設定) に、NSDiscardableContentオブジェクトに対して次のような動作を行うようです。

  • キャッシュからオブジェクトが削除されるときに、discardContentIfPossibleが呼ばれる
  • objectForKey:を呼び出したときに、isContentDiscardedが呼ばれる

NSCacheとNSDiscardableContentの利用例

いくつかありましたが、NSCacheとNSDiscardableContentの連携した例は見つけられず。

参考資料

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。