Verwendung von NSCache

121

Kann jemand ein Beispiel geben, wie man NSCacheeinen String zwischenspeichert? Oder hat jemand einen Link zu einer guten Erklärung? Ich kann anscheinend keine finden ..

Thizzer
quelle
7
Obwohl ich eine große Menge Kakao gesehen habe, habe ich noch nie von NSCache gehört. Gute Frage!
Nektarios
Ich habe hier eine iterierbare Version von NSCache erstellt. Fühlen Sie sich frei, dazu beizutragen: github.com/gregkrsak/GKCache
Greg M. Krsak

Antworten:

134

Sie verwenden es genauso, wie Sie es verwenden würden NSMutableDictionary. Der Unterschied besteht darin, dass beim NSCacheErkennen eines übermäßigen Speicherdrucks (dh beim Zwischenspeichern zu vieler Werte) einige dieser Werte freigegeben werden, um Platz zu schaffen.

Wenn Sie diese Werte zur Laufzeit neu erstellen können (durch Herunterladen aus dem Internet, durch Ausführen von Berechnungen usw.), entspricht dies NSCachemöglicherweise Ihren Anforderungen. Wenn die Daten nicht neu erstellt werden können (z. B. Benutzereingaben, zeitkritische Daten usw.), sollten Sie sie nicht in einer Datei speichernNSCache da sie dort zerstört werden.

Beispiel, ohne Berücksichtigung der Thread-Sicherheit:

// 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];
}
Jonathan Grynspan
quelle
1
Wie instanziiere ich das NSCache-Objekt? Ich scheine jedes Mal, wenn ich die App starte, alle zwischengespeicherten Informationen zu verlieren. Ich benutze; [[NSCache alloc] init]
Thizzer
17
Es ist kein permanenter Cache auf der Festplatte. Es befindet sich nur im Speicher. Ja, es wird jedes Mal zerstört, wenn Ihre App nicht mehr ausgeführt wird.
Jonathan Grynspan
Wird dieser Cache beibehalten, wenn die Anwendung in den Hintergrund gelangt? (dh danach applicationDidEnterBackground)
Barfoon
Wenn die Anwendung nicht beendet wird und das NSCacheObjekt nicht freigegeben wird, bleibt es im Speicher. Der Inhalt kann jedoch weiterhin ausgesondert werden.
Jonathan Grynspan
3
Nein. Eine Behauptung behauptet, dass etwas wahr ist, dh dass die darin enthaltene Aussage wahr sein soll. Wir behaupten, dass die Objektzuweisung und / oder -erstellung erfolgreich war.
Jonathan Grynspan
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"];
Gabriel.Massana
quelle
3
Ja. Speichern: [imagesDictionary setObject: imageData forKey: @ "KEY"]; Abrufen: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
Gabriel.Massana
2
Daten im Chache speichern: [imagesCache setObject: imageData forKey: @ "KEY"];
Kas-Kad
1
Ich habe gerade den Beitrag geändert geändert: imagesDictionary for imagesCache. Thx
Gabriel.Massana
Ein gleichwertiges schnelles Beispiel?
Jasper
9

Beispielcode zum Zwischenspeichern einer Zeichenfolge mit NSCache in Swift:

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"

Um eine einzelne app-weite Instanz von NSCache (ein Singleton) zu erstellen, können Sie NSCache problemlos erweitern, um eine sharedInstance-Eigenschaft hinzuzufügen. Fügen Sie einfach den folgenden Code in eine Datei mit dem Namen NSCache + Singleton.swift ein:

import Foundation

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

Sie können den Cache dann an einer beliebigen Stelle in der App verwenden:

NSCache.sharedInstance.setObject("String for key 2", forKey: "Key2")
var result2 = NSCache.sharedInstance.objectForKey("Key2") as String
println(result2) // Prints "String for key 2"
PointZeroTwo
quelle
3
Wissen Sie, wie Sie dies in Swift 3 implementieren können?
Andy
3
Dies sollte funktionieren: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB
6

Beispielprojekt Fügen Sie Ihrem Projekt die Dateien CacheController.h und .m aus dem Beispielprojekt hinzu. Geben Sie in der Klasse, in der Sie Daten zwischenspeichern möchten, den folgenden Code ein.

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

Sie können damit jedes Objekt festlegen

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

abrufen

Wichtig: Die NSCache-Klasse enthält verschiedene Richtlinien zum automatischen Entfernen. Wenn Sie die Daten für eine dauerhafte Speicherung zwischenspeichern oder zwischengespeicherte Daten zu einem bestimmten Zeitpunkt entfernen möchten, lesen Sie diese Antwort .

Ajumal
quelle
1

Sollten die zwischengespeicherten Objekte nicht das NSDiscardableContent-Protokoll implementieren?

Aus der NSCache-Klassenreferenz: Ein allgemeiner Datentyp, der in NSCache-Objekten gespeichert ist, ist ein Objekt, das das NSDiscardableContent-Protokoll implementiert. Das Speichern dieses Objekttyps in einem Cache hat Vorteile, da sein Inhalt verworfen werden kann, wenn er nicht mehr benötigt wird, wodurch Speicherplatz gespart wird. Standardmäßig werden NSDiscardableContent-Objekte im Cache automatisch aus dem Cache entfernt, wenn ihr Inhalt verworfen wird. Diese Richtlinie zum automatischen Entfernen kann jedoch geändert werden. Wenn ein NSDiscardableContent-Objekt in den Cache gestellt wird, ruft der Cache beim Entfernen discardContentIfPossible auf.

Phönix
quelle
1
Sie können das NSDiscardableContent-Protokoll implementieren, dies ist jedoch nicht erforderlich. Wie es scheint, wird NSDiscardableContent immer aus NSCache entfernt, wenn keine Referenzen mehr vorhanden sind. Andere Objekte als das NSDiscardableContent-Objekt werden im NSCache gespeichert, bis der Arbeitsspeicher knapp ist und der NSCache gelöscht wird.
Thizzer