Come utilizzare NSCache


121

Qualcuno può fornire un esempio su come utilizzare NSCacheper memorizzare nella cache una stringa? O qualcuno ha un link a una buona spiegazione? Non riesco a trovarne nessuno ..


7
Nonostante abbia visto una quantità enorme di Cocoa, non ho mai sentito parlare di NSCache. Buona domanda!
Nektarios

Ho creato una versione iterabile di NSCache, qui. Sentiti libero di contribuire: github.com/gregkrsak/GKCache
Greg M. Krsak

Risposte:


134

Lo usi nello stesso modo in cui lo useresti NSMutableDictionary. La differenza è che quando NSCacherileva una pressione eccessiva della memoria (cioè memorizza troppi valori nella cache) rilascerà alcuni di quei valori per fare spazio.

Se è possibile ricreare quei valori in fase di esecuzione (scaricando da Internet, facendo calcoli, qualunque cosa) allora NSCache potrebbe soddisfare le tue esigenze. Se i dati non possono essere ricreati (ad esempio, è l'input dell'utente, è sensibile al tempo, ecc.), Allora non dovresti memorizzarlo in un NSCacheperché verrà distrutto lì.

Esempio, senza tenere conto della sicurezza dei thread:

// 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
come istanziare l'oggetto NSCache? Mi sembra di perdere tutte le informazioni memorizzate nella cache ogni volta che eseguo l'app. Io uso; [[NSCache alloc] init]
Thizzer

17
Non è una cache permanente su disco. È solo in memoria, quindi sì, viene distrutto ogni volta che la tua app smette di funzionare.
Jonathan Grynspan

Questa cache viene mantenuta dopo che l'applicazione è entrata nel backgruond? (cioè dopo applicationDidEnterBackground)
barfoon

Se l'applicazione non viene terminata e l' NSCacheoggetto non viene deallocato, sì, rimarrà in memoria. Tuttavia, il suo contenuto potrebbe essere ancora soggetto ad abbattimento.
Jonathan Grynspan

3
No. Un'asserzione asserisce che qualcosa è vero, cioè che l'affermazione all'interno dovrebbe essere vera. Stiamo affermando che l'assegnazione e / o la creazione dell'oggetto ha avuto successo.
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"];

3
Sì. Salva: [imagesDictionary setObject: imageData forKey: @ "KEY"]; recuperare: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
Gabriel.Massana

2
salva i dati in chache: [imagesCache setObject: imageData forKey: @ "KEY"];
kas-kad

1
Ho appena modificato il post modificato: imagesDictionary per imagesCache. Thx
Gabriel.Massana

Un rapido esempio equivalente?
Jasper

9

Codice di esempio per memorizzare una stringa nella cache utilizzando 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"

Per creare una singola istanza a livello di app di NSCache (un singleton), puoi facilmente estendere NSCache per aggiungere una proprietà sharedInstance. Basta inserire il codice seguente in un file chiamato qualcosa come NSCache + Singleton.swift:

import Foundation

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

È quindi possibile utilizzare la cache ovunque nell'app:

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
sai come implementarlo in swift 3?
Andy

3
Dovrebbe funzionare: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB

6

progetto di esempio Aggiungi il file CacheController.he .m dal progetto di esempio al tuo progetto. Nella classe in cui desideri memorizzare nella cache i dati, inserisci il codice seguente.

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

puoi impostare qualsiasi oggetto usando questo

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

per recuperare

Importante: la classe NSCache incorpora vari criteri di rimozione automatica. se vuoi memorizzare nella cache i dati in modo permanente o se desideri rimuovere i dati memorizzati nella cache in un momento specifico, vedi questa risposta .


1

Gli oggetti memorizzati nella cache non dovrebbero implementare il protocollo NSDiscardableContent?

Dal riferimento alla classe NSCache: un tipo di dati comune archiviato negli oggetti NSCache è un oggetto che implementa il protocollo NSDiscardableContent. Memorizzare questo tipo di oggetto in una cache ha dei vantaggi, perché il suo contenuto può essere scartato quando non è più necessario, risparmiando così memoria. Per impostazione predefinita, gli oggetti NSDiscardableContent nella cache vengono automaticamente rimossi dalla cache se il loro contenuto viene scartato, sebbene questa politica di rimozione automatica possa essere modificata. Se un oggetto NSDiscardableContent viene inserito nella cache, la cache chiama discardContentIfPossible su di esso al momento della sua rimozione.


1
È possibile implementare il protocollo NSDiscardableContent ma non è necessario. Come sembra NSDiscardableContent viene sempre rimosso da NSCache quando non ci sono più riferimenti. Gli oggetti diversi dall'oggetto NSDiscardableContent vengono archiviati in NSCache fino a quando "la memoria è scarsa" e NSCache verrà cancellato.
Thizzer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.