NSCacheの使い方


121

誰かNSCacheが文字列をキャッシュする方法の例を挙げられますか?または誰かが良い説明へのリンクを持っていますか?見つからないようです。


7
大量のCocoaを見たにもかかわらず、NSCacheについて聞いたことがありません。良い質問!
Nektarios、2011

ここでは、NSCacheの反復可能なバージョンを作成しました。それに貢献してお気軽
Greg M. Krsak

回答:


134

使用方法と同じように使用しますNSMutableDictionary。違いは、NSCache過度のメモリプレッシャーを検出した場合(つまり、キャッシュする値が多すぎる場合)、それらの値の一部を解放して領域を空けることです。

実行時にこれらの値を(インターネットからダウンロードしたり、計算を行ったりして)再作成できる場合はNSCache、ニーズに合う可能性があります。データを再作成できない場合(たとえば、ユーザー入力、時間依存など)は、データがNSCacheそこに破棄されるため、に保存しないでください。

スレッドセーフを考慮しない例:

// Your cache should have a lifetime beyond the method or handful of methods
// that use it. For example, you could make it a field of your application
// delegate, or of your view controller, or something like that. Up to you.
NSCache *myCache = ...;
NSAssert(myCache != nil, @"cache object is missing");

// Try to get the existing object out of the cache, if it's there.
Widget *myWidget = [myCache objectForKey: @"Important Widget"];
if (!myWidget) {
    // It's not in the cache yet, or has been removed. We have to
    // create it. Presumably, creation is an expensive operation,
    // which is why we cache the results. If creation is cheap, we
    // probably don't need to bother caching it. That's a design
    // decision you'll have to make yourself.
    myWidget = [[[Widget alloc] initExpensively] autorelease];

    // Put it in the cache. It will stay there as long as the OS
    // has room for it. It may be removed at any time, however,
    // at which point we'll have to create it again on next use.
    [myCache setObject: myWidget forKey: @"Important Widget"];
}

// myWidget should exist now either way. Use it here.
if (myWidget) {
    [myWidget runOrWhatever];
}

1
NSCacheオブジェクトをインスタンス化する方法 アプリを実行するたびに、キャッシュされた情報がすべて失われるようです。私が使う; [[NSCache alloc] init]
Thizzer

17
ディスク上の永続的なキャッシュではありません。これはメモリにのみ存在するため、アプリの実行が停止するたびに破棄されます。
ジョナサン・グリンスパン

アプリケーションがバックグラウンドに入った後、このキャッシュは維持されますか?(例:後applicationDidEnterBackground
barfoon

アプリケーションが終了せず、NSCacheオブジェクトの割り当てが解除されない場合、はい、それはメモリに残ります。ただし、その内容はカリングの対象になる場合があります。
ジョナサングリンスパン

3
いいえ。アサーションは、何かが真であること、つまり、その中のステートメントが真であることが期待されることを表明します。オブジェクトの割り当てや作成が成功したと断言します。
ジョナサングリンスパン

19
@implementation ViewController
{    
    NSCache *imagesCache;    
}


- (void)viewDidLoad
{    
    imagesCache = [[NSCache alloc] init];
}


// How to save and retrieve NSData into NSCache
NSData *imageData = [imagesCache objectForKey:@"KEY"];
[imagesCache setObject:imageData forKey:@"KEY"];

3
はい。保存:[imagesDictionary setObject:imageData forKey:@ "KEY"]; 取得:NSData * imageData = [imagesCache objectForKey:@ "KEY"];
Gabriel.Massana 2013

2
データをchacheに保存します:[imagesCache setObject:imageData forKey:@ "KEY"];
kas-kad

1
変更された投稿を編集しました:imagesCacheのimagesDictionary。Thx
Gabriel.Massana

同等の迅速な例?
ジャスパー2015年

9

SwiftでNSCacheを使用して文字列をキャッシュするためのサンプルコード:

var cache = NSCache()
cache.setObject("String for key 1", forKey: "Key1")
var result = cache.objectForKey("Key1") as String
println(result) // Prints "String for key 1"

NSCacheの単一のアプリ全体のインスタンス(シングルトン)を作成するには、NSCacheを簡単に拡張して、sharedInstanceプロパティを追加します。NSCache + Singleton.swiftのようなファイルに次のコードを挿入するだけです。

import Foundation

extension NSCache {
    class var sharedInstance : NSCache {
        struct Static {
            static let instance : NSCache = NSCache()
        }
        return Static.instance
    }
}

その後、アプリのどこでもキャッシュを使用できます。

NSCache.sharedInstance.setObject("String for key 2", forKey: "Key2")
var result2 = NSCache.sharedInstance.objectForKey("Key2") as String
println(result2) // Prints "String for key 2"

3
これをSwift 3に実装する方法を知っていますか?
アンディ

3
これは動作するはずです: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB

6

サンプルプロジェクトサンプルプロジェクトからプロジェクト にCacheController.hおよび.mファイルを追加します。データをキャッシュしたいクラスに、以下のコードを記述します。

[[CacheController storeInstance] setCache:@"object" forKey:@"objectforkey" ];

これを使用して任意のオブジェクトを設定できます

[[CacheController storeInstance] getCacheForKey:@"objectforkey" ];

取得する

重要:NSCacheクラスには、さまざまな自動削除ポリシーが組み込まれています。永続的にデータをキャッシュする場合、または特定の時間にキャッシュデータを削除する場合は、 この回答を参照してください


1

キャッシュされたオブジェクトはNSDiscardableContentプロトコルを実装すべきではありませんか?

NSCacheクラスリファレンスから:NSCacheオブジェクトに格納される一般的なデータ型は、NSDiscardableContentプロトコルを実装するオブジェクトです。このタイプのオブジェクトをキャッシュに格納すると、コンテンツが不要になったときに破棄できるため、メモリを節約できるという利点があります。デフォルトでは、キャッシュ内のNSDiscardableContentオブジェクトは、コンテンツが破棄されると自動的にキャッシュから削除されますが、この自動削除ポリシーは変更できます。NSDiscardableContentオブジェクトがキャッシュに入れられると、キャッシュは削除時にdiscardContentIfPossibleを呼び出します。


1
NSDiscardableContentプロトコルを実装できますが、これは必須ではありません。参照がない場合、NSDiscardableContentは常にNSCacheから削除されるようです。NSDiscardableContentオブジェクト以外のオブジェクトは、「メモリが不足」してNSCacheがクリアされるまで、NSCacheに格納されます。
Thizzer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.