データをキャッシュするときに便利そうな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の連携した例は見つけられず。
- ninjinkun/NSCacheTest · GitHub: NSCacheをスレッドで楽に利用できるディクショナリとして利用する例 (発表資料)
- jakemarsh/JMImageCache · GitHub: NSCacheを継承した独自の画像キャッシュクラスを作成例
- EXObjectProxy.m - entropy20 - Google Project Hosting: NSDiscardableContentの例
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。