Jak korzystać z NSCache


121

Czy ktoś może podać przykład, jak używać NSCachedo buforowania ciągu? Czy ktoś ma link do dobrego wyjaśnienia? Nie mogę znaleźć żadnego ...


7
Pomimo zobaczenia ogromnej ilości kakao nigdy nie słyszałem o NSCache. Dobre pytanie!
— Nektarios

Stworzyłem tutaj iterowalną wersję NSCache. Zapraszam do współtworzenia: github.com/gregkrsak/GKCache
— Greg M. Krsak

Odpowiedzi:


134

Używasz go w taki sam sposób, jak byś używał NSMutableDictionary. Różnica polega na tym, że gdy NSCachewykryje nadmierne obciążenie pamięci (tj. Buforuje zbyt wiele wartości), zwolni niektóre z tych wartości, aby zrobić miejsce.

Jeśli możesz odtworzyć te wartości w czasie wykonywania (pobierając je z Internetu, wykonując obliczenia, cokolwiek), NSCachemoże to odpowiadać Twoim potrzebom. Jeśli danych nie można odtworzyć (np. Są to dane wprowadzone przez użytkownika, są wrażliwe na czas itp.), Nie należy ich przechowywać w pliku, NSCacheponieważ zostaną tam zniszczone.

Przykład bez uwzględnienia bezpieczeństwa wątków:

// 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
jak utworzyć wystąpienie obiektu NSCache? Wydaje mi się, że tracę wszystkie informacje z pamięci podręcznej za każdym razem, gdy uruchamiam aplikację. Używam; [[NSCache assign] init]
— Thizzer

17
To nie jest stała pamięć podręczna na dysku. Jest tylko w pamięci, więc tak, jest niszczony za każdym razem, gdy aplikacja przestaje działać.
— Jonathan Grynspan

Czy ta pamięć podręczna jest utrzymywana, gdy aplikacja przechodzi do backgruond? (czyli po applicationDidEnterBackground)
— barfoon

Jeśli aplikacja nie zostanie zakończona, a NSCacheobiekt nie zostanie zwolniony, to tak, pozostanie w pamięci. Jednak jego zawartość może nadal podlegać ubojowi.
— Jonathan Grynspan,

3
Nie. Stwierdzenie twierdzi, że coś jest prawdą, tj. Że oczekuje się, że stwierdzenie wewnątrz będzie prawdziwe. Oświadczamy, że przypisanie i / lub utworzenie obiektu zakończyło się pomyślnie.
— 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
Tak. Zapisz: [imagesDictionary setObject: imageData forKey: @ "KEY"]; retrieve: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
— Gabriel.Massana

2
zapisz dane do chache: [imagesCache setObject: imageData forKey: @ "KEY"];
— kas-kad

1
Właśnie zredagowałem zmieniony post: imagesDictionary for imagesCache. Dzięki
— Gabriel.Massana

Równoważny szybki przykład?
— Jasper

9

Przykładowy kod do buforowania ciągu przy użyciu NSCache w języku 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"

Aby utworzyć pojedyncze wystąpienie NSCache dla całej aplikacji (singleton), możesz łatwo rozszerzyć NSCache, aby dodać właściwość sharedInstance. Po prostu umieść następujący kod w pliku o nazwie podobnej do NSCache + Singleton.swift:

import Foundation

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

Następnie możesz użyć pamięci podręcznej w dowolnym miejscu aplikacji:

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
czy wiesz, jak to zaimplementować w Swift 3?
— Andy

3
To powinno działać: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
— AmitaiB

6

przykładowy projekt Dodaj plik CacheController.h i .m z przykładowego projektu do projektu. W klasie, w której chcesz przechowywać dane w pamięci podręcznej, umieść poniższy kod.

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

możesz ustawić dowolny obiekt za pomocą tego

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

odzyskać

Ważne: Klasa NSCache zawiera różne zasady automatycznego usuwania. jeśli chcesz buforować dane na stałe lub chcesz usunąć dane z pamięci podręcznej w określonym czasie, zobacz tę odpowiedź .


1

Czy buforowane obiekty nie powinny implementować protokołu NSDiscardableContent?

Z opisu klasy NSCache: Typowym typem danych przechowywanym w obiektach NSCache jest obiekt implementujący protokół NSDiscardableContent. Przechowywanie tego typu obiektu w pamięci podręcznej ma zalety, ponieważ jego zawartość można wyrzucić, gdy nie jest już potrzebna, oszczędzając w ten sposób pamięć. Domyślnie obiekty NSDiscardableContent w pamięci podręcznej są automatycznie usuwane z pamięci podręcznej, jeśli ich zawartość zostanie odrzucona, chociaż tę zasadę automatycznego usuwania można zmienić. Jeśli obiekt NSDiscardableContent zostanie umieszczony w pamięci podręcznej, pamięć podręczna wywoła na nim discardContentIfPossible po jego usunięciu.


1
Możesz zaimplementować protokół NSDiscardableContent, ale nie jest to wymagane. Jak się wydaje, NSDiscardableContent jest zawsze usuwana z NSCache, gdy nie ma już odwołań. Obiekty inne niż obiekt NSDiscardableContent są przechowywane w NSCache do momentu, gdy „pamięć jest napięta” i nie zostanie wyczyszczona pamięć NSCache.
— Thizzer
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.