NSCache
イメージなどをファイルから読み込む、またはon the flyで処理して利用するにはちと重いデータなどは、一度処理して結果を NSCache
に保存しておく事は TableView などの表示には有効です。
ところが、NSCache
とのインターフェースは AnyObject
なので、Swiftで使うときはいちいち as? MyObject
とかキャストしなくてはなりません。
そこで、NSCache
をラップして Generics で使えるようにしてみました。
import Foundation
class ZCache<T: AnyObject> {
private var cache = NSCache()
var delegate: NSCacheDelegate? {
get { return self.delegate }
set { self.cache.delegate = newValue }
}
var name: String {
get { return self.cache.name }
set { self.cache.name = newValue }
}
func objectForKey(key: AnyObject) -> T? {
return self.cache.objectForKey(key) as? T
}
func setObject(obj: T, forKey key: AnyObject) {
self.cache.setObject(obj, forKey: key)
}
func setObject(obj: T, forKey key: AnyObject, cost g: Int) {
self.cache.setObject(obj, forKey: key, cost: g)
}
func removeObjectForKey(key: AnyObject) {
self.cache.removeObjectForKey(key)
}
func removeAllObjects() {
self.cache.removeAllObjects()
}
var totalCostLimit: Int {
get { return self.cache.totalCostLimit }
set { self.cache.totalCostLimit = newValue }
}
var countLimit: Int {
get { return self.cache.countLimit }
set { self.cache.countLimit = newValue }
}
var evictsObjectsWithDiscardedContent: Bool {
get { return self.cache.evictsObjectsWithDiscardedContent }
set { self.evictsObjectsWithDiscardedContent = newValue }
}
// MARK: -
subscript(key: AnyObject) -> T? {
get { return self.cache.objectForKey(key) as? T }
set {
if let newValue = newValue {
self.cache.setObject(newValue, forKey: key)
}
else {
self.cache.removeObjectForKey(key)
}
}
}
}
NSCache
のすべてのメソッドをラップしていますので、オリジナルと同様に利用できるはずです。加えて subscript(key: AnyObject)
でアクセスできるようにしてみました。その際、セッターは nil を設定した場合は、オブジェクトを remove しています。
generics で実装されていますので、毎回毎回キャストする必要はなく、Swift らしくコーディングを進めることができるのではないでしょうか?
利用例を紹介いたします。
var cache = ZCache<NSImage>()
cache["1"] = NSImage(named: "1") // assume there is!!
let image1 = cache["1"] // image
cache["1"] = nil
let image2 = cache["1"] // nil
コードは gist からも入手可能です。
https://gist.github.com/codelynx/29b2c2a36d290cec58a009ef712f33b0
それでは、みなさん、Have a happy coding!!
関連情報
Swift で Key や Value に弱参照が使える Dictionary 的な方法を考える
http://qiita.com/codelynx/items/27b8dd8c3ac49f6316ef
環境情報
swift --version
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)