2011-09-05 11 views
9

Quiero almacenar varios objetos en una NSCache y hacer que se eliminen automáticamente cuando aparece una advertencia de memoria. Así que escribí la siguiente implementación NSDiscardableContent que uso para envolver las instancias que pongo en los valores en una NSCache.Cómo utilizar NSCache con una implementación genérica de NSDiscardableContent

Pero nunca veo que se eliminen de la memoria caché cuando ejecuto "Simular advertencia de memoria". ¿Hay algún problema con mi implementación de NSDiscardableContent? ¿O tengo que hacer algo más para que la memoria caché deje caer los valores cuando se produce una advertencia de memoria?

/** @brief generic implementation of the NSDiscardableContent for storing objects in an NSCache */ 
@interface GenericDiscardableObject : NSObject<NSDiscardableContent> 
@property (nonatomic, retain) id object; 
@property (nonatomic) NSUInteger accessCount; 
+ (GenericDiscardableObject *)discardableObject:(id)ob; 
@end 

@implementation GenericDiscardableObject 
@synthesize object, accessCount; 

+ (GenericDiscardableObject *)discardableObject:(id)ob { 
    GenericDiscardableObject *discardable = [[GenericDiscardableObject alloc] init]; 
    discardable.object = ob; 
    discardable.accessCount = 0u; 
    return [discardable autorelease]; 
} 

- (void)dealloc { 
    self.object = nil; 
    [super dealloc]; 
} 

- (BOOL)beginContentAccess { 
    if (!self.object) 
     return NO; 
    self.accessCount = self.accessCount + 1; 
    return YES; 
} 

- (void)endContentAccess { 
    if (self.accessCount) 
     self.accessCount = self.accessCount - 1; 
} 

- (void)discardContentIfPossible { 
    if (!self.accessCount) 
     self.object = nil; 
} 

- (BOOL)isContentDiscarded { 
    return self.object == nil; 
} 
@end 
+0

Esto no es una respuesta, pero en general es una mala práctica usar una configuración en su método dealloc; no sabe si alguien está escuchando KVO, etc. Simplemente haga '[object release]' en su lugar :) – deanWombourne

+0

@deanWombourne There no debería haber nadie escuchando el objeto en - (void) dealloc, ya que el objeto ya no se conserva. ¿O entiendo algo mal? Solo estoy preguntando porque prefiero desmantelar propiedades, también ... – radiospiel

+0

Simplemente porque ya no está retenido no significa que nadie está escuchando;) Apple aborda el tema: http://developer.apple.com/library/ mac/# documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html y una conversación más interesante aquí: http://www.cocoabuilder.com/archive/cocoa/242096-avoiding-kvo-in-dealloc.html – deanWombourne

Respuesta

8

Hasta donde puedo decir, el comportamiento predeterminado de NSCache es tirar los objetos cuando hay una advertencia de memoria.

Así que puedes simplemente almacenar tus objetos "desnudos" en tu caché como si fuera un NSDictionary, y se limpiarán cuando la memoria se ponga tensa. No tiene que envolverlos en un objeto descartable ni hacer nada más. P.ej.

[myCache setObject:foo forKey:@"bar"]; // foo will be released if memory runs low 

No es muy claro a partir de la documentación, pero por lo que puedo decir, el propósito del protocolo <NSDiscardableContent> contenido es para implementar un comportamiento más complejo mediante el cual un objeto puede liberar subcomponentes cuando queda poca memoria, sin liberar necesariamente sí mismo.

Cuestiones relacionadas