2012-06-02 13 views

Respuesta

7

Lo mejor es tratar NSCache como una caja negra, tanto como pueda.

De Caching and Purgeable Memory (el énfasis es mío):

Al añadir elementos a un caché, puede especificar un valor de coste de estar asociado con cada par clave-valor. Llame al método setTotalCostLimit: para establecer el valor máximo de la suma de todos los costos de los objetos en caché. Por lo tanto, cuando se agrega un objeto que empuja el totalCost sobre el totalCostLimit, el caché puede desalojar automáticamente algunos de sus objetos para volver a estar por debajo del umbral. Este proceso de desalojo no está garantizado, por lo que tratar de manipular los valores cost para lograr un comportamiento específico podría ser perjudicial para el rendimiento de la memoria caché. pase en 0 para la cost si no tienen nada útil, o utiliza el método setObject:forKey:, que no requiere un coste para ser aprobada en

. Nota: El límite de recuento y el límite de costo total que no están estrictamente aplicadas. Es decir, cuando la memoria caché supera uno de sus límites, algunos de sus objetos pueden ser desalojados inmediatamente, más tarde o nunca, todo dependiendo de los detalles de implementación de la memoria caché.

+2

¿Es una buena idea para observar sobre alerta memoria y purgar la caché, entonces? –

+1

@EvilNodoer Haciendo algo de experimentación, descubrí que si bien no responde a 'UIApplicationDidReceiveMemoryWarningNotification', en realidad desaloja sus objetos automáticamente en situaciones de poca memoria (debe usar algún otro mecanismo). – Rob

+0

@EvilNodoer Por cierto, debo retractar mi comentario sobre 'NSCache' respondiendo a la presión de la memoria, ya que esto ha cambiado en iOS 7. Observar' UIApplicationDidReceiveMemoryWarningNotification' sería prudente. Ver http://stackoverflow.com/questions/19546054/nscache-crashing-when-memory-limit-is-reached-only-on-ios-7 – Rob

8

NSCache no responde a UIApplicationDidReceiveMemoryWarningNotification, pero lo hace de forma automática desalojar a sus objetos en situaciones de poca memoria, obviamente, utilizando algún otro mecanismo.

Si bien anteriormente sugerí observar UIApplicationDidReceiveMemoryWarningNotification, este no es el caso. No es necesario un manejo especial para situaciones de poca memoria, ya que NSCache maneja esto automáticamente.


Actualización:

A partir de iOS 7, el NSCache no sólo no responde a las advertencias de memoria, pero también no parece que purgar de forma correcta en la memoria de la presión, ya sea (ver NSCache crashing when memory limit is reached (only on iOS 7)).

I subclase NSCache observar UIApplicationDidReceiveMemoryWarningNotification, y purgar la caché tras la advertencia de memoria:

@interface AutoPurgeCache : NSCache 
@end 

@implementation AutoPurgeCache 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 

    // if not ARC, also 
    // 
    // [super dealloc]; 
} 

@end 
Cuestiones relacionadas