Como usar o NSCache

121

Alguém pode dar um exemplo de como usar NSCachepara armazenar em cache uma string? Ou alguém tem um link para uma boa explicação? Não consigo encontrar nenhum ..

Thizzer
fonte
7
Apesar de ver uma quantidade enorme de cacau, nunca ouvi falar do NSCache. Boa pergunta!
Nektarios
Criei uma versão iterável do NSCache, aqui. Sinta-se à vontade para contribuir: github.com/gregkrsak/GKCache
Greg M. Krsak

Respostas:

134

Você o usa da mesma maneira que usaria NSMutableDictionary. A diferença é que, quando NSCachedetecta pressão excessiva na memória (ou seja, está armazenando muitos valores em cache), ele libera alguns desses valores para liberar espaço.

Se você pode recriar esses valores em tempo de execução (baixando da Internet, fazendo cálculos, o que for), NSCachepode atender às suas necessidades. Se os dados não puderem ser recriados (por exemplo, são dados do usuário, são sensíveis ao tempo, etc.), você não deve armazená-los em um arquivo NSCacheporque eles serão destruídos lá.

Exemplo, sem levar em consideração a segurança do encadeamento:

// 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
fonte
1
como instanciar o objeto NSCache? Parece que perdi todas as informações em cache sempre que executo o aplicativo. Eu uso; [[NSCache aloc] init]
Thizzer 26/04/11
17
Não é um cache permanente no disco. Está apenas na memória; portanto, sim, é destruído sempre que seu aplicativo para de executar.
22611 Jonathan Grynspan
Esse cache é mantido quando após o aplicativo entrar no segundo plano? (ie depois applicationDidEnterBackground)
barfoon
Se o aplicativo não for finalizado e o NSCacheobjeto não for desalocado, sim, ele permanecerá na memória. Seu conteúdo ainda pode estar sujeito a abate.
Jonathan Grynspan
3
Não. Uma afirmação afirma que algo é verdadeiro, ou seja, que a declaração contida é esperada verdadeira. Estamos afirmando que a atribuição e / ou criação do objeto foi bem-sucedida.
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
fonte
3
Sim. Salvar: [imagesDictionary setObject: imageData forKey: @ "KEY"]; recuperar: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
precisa saber é o seguinte
2
salve os dados no chache: [imagesCache setObject: imageData forKey: @ "KEY"];
precisa saber é o seguinte
1
Acabei de editar a postagem alterada: imagesDictionary for imagesCache. Thx
Gabriel.Massana
Um exemplo rápido equivalente?
Jasper
9

Código de exemplo para armazenar em cache uma sequência usando o NSCache no 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"

Para criar uma instância única do NSCache em todo o aplicativo, você pode estender o NSCache facilmente para adicionar uma propriedade sharedInstance. Basta colocar o seguinte código em um arquivo chamado NSCache + Singleton.swift:

import Foundation

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

Você pode usar o cache em qualquer lugar do aplicativo:

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
fonte
3
você sabe como implementar isso no swift 3?
22416 Andy
3
Isso deve funcionar: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB 14/11
6

projeto de amostra Adicione o arquivo CacheController.he .m do projeto de amostra ao seu projeto. Na classe em que você deseja armazenar em cache os dados, coloque o código abaixo.

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

você pode definir qualquer objeto usando este

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

recuperar

Importante: A classe NSCache incorpora várias políticas de remoção automática. se você deseja armazenar em cache os dados para permanente ou remover dados em cache em um horário específico, consulte esta resposta .

Ajumal
fonte
1

Os objetos em cache não devem implementar o protocolo NSDiscardableContent?

Na referência da classe NSCache: Um tipo de dados comum armazenado nos objetos NSCache é um objeto que implementa o protocolo NSDiscardableContent. Armazenar esse tipo de objeto em um cache traz benefícios, pois seu conteúdo pode ser descartado quando não for mais necessário, economizando memória. Por padrão, os objetos NSDiscardableContent no cache são removidos automaticamente do cache se seu conteúdo for descartado, embora essa política de remoção automática possa ser alterada. Se um objeto NSDiscardableContent for colocado no cache, ele chamará discardContentIfPossible após a remoção.

Fénix
fonte
1
Você pode implementar o protocolo NSDiscardableContent, mas isso não é necessário. Como parece, NSDiscardableContent é sempre removido do NSCache quando não há mais referências. Objetos diferentes do objeto NSDiscardableContent são armazenados no NSCache até que haja 'memória insuficiente' e o NSCache seja limpo.
Thizzer