2010-01-29 11 views
5

CSURLCache está diseñado para almacenar en caché los recursos para la exploración sin conexión, ya que NSURLCache solo almacena datos en la memoria.NSURLCache se bloquea con objetos liberados automáticamente, pero de lo contrario

Si cachedResponse se libera automáticamente antes de devolver la aplicación se bloquea, si no, los objetos simplemente se filtran.

Cualquier luz que pueda arrojarse sobre esto sería muy apreciada.

Tenga en cuenta que stringByEncodingURLEntities es un método de categoría en NSString.

@interface CSURLCache : NSURLCache {} @end 

@implementation CSURLCache 

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request 
{ 
    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[[[request URL] absoluteString] stringByEncodingURLEntities]]; 

    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) 
    { 
     NSData *data = [[NSData alloc] initWithContentsOfFile:path]; 
     NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[request URL] 
                  MIMEType:nil 
               expectedContentLength:[data length] 
                textEncodingName:nil]; 

     NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response 
                         data:data]; 
     [response release]; 
     [data release]; 

     return cachedResponse; 
    } 

    return nil; 
} 

@end 

ACTUALIZACIÓN: Después de enviar un radar a Apple parece que este es un problema conocido (radar # 7640470).

+0

¿Estás seguro de que se han filtrado si no se han lanzado de forma automática? ¿Y está seguro de que su programa se bloquea porque intenta liberarlos? Las reglas de administración de memoria indican claramente que usted sería el responsable de liberar ese objeto. – zneak

+3

Sí, definitivamente gotean si no se liberan automáticamente. El programa se bloquea porque se envía un mensaje de retención a un objeto desasignado –

Respuesta

1
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request 

Bueno, esto no es una alloc, new, o copy método ...

... y CSURLCache no se sostiene en que el objeto en cualquier lugar, así que no es dueño de ella.

Por lo tanto, debe liberarlo automáticamente.

Por supuesto, eso significa que el objeto está condenado a menos que algo lo conserve. Tu aplicación se bloqueó porque intentó usar el objeto después de que el objeto murió.

Ejecute su aplicación en Instrumentos con la plantilla Zombies. Mire dónde se bloquea la aplicación y qué estaba haciendo cuando se llamó al cachedResponseForRequest:. La persona que llama debe ser propietaria del objeto hasta el momento en que la aplicación fallaría de lo contrario, y luego liberarlo.

+0

La aplicación se cuelga porque un mensaje de retención se envía a un objeto desasignado, sin embargo, con una investigación posterior, NO la copia en caché. No obstante, no puedo averiguar a qué objeto se envía el mensaje. Si habilito NSZombieEnabled, se imprime "[No un tipo retener]". –

+0

No crea que esta sea la solución, ya que NSCachedResponse no es el objeto que está causando el bloqueo cuando se lanza (está fallando como parte de su dealloc, lo que significa que algo retenido por NSCachedResponse está siendo liberado) – BadPirate

+0

outtru.mp : Implementar la administración de la memoria correctamente no es opcional (no hacerlo significaría que la persona que pregunta tendría dos errores), y el instrumento Zombies es cómo determinaría qué objeto se libera en exceso y cuál fue la versión extraña. Entonces, el primer aspecto es parte de la solución (la fuga puede ser preferible a una colisión, pero una vez que se elimina la colisión, la fuga también debe serlo), y la segunda es parte de la investigación del problema real. –

Cuestiones relacionadas