2010-01-29 3 views
5

CSURLCache è progettato per memorizzare nella cache le risorse per la navigazione offline, poiché NSURLCache memorizza solo i dati in memoria.NSURLCache si arresta in modo anomalo con oggetti autoreleased, ma perde altrimenti

Se cachedResponse viene rilasciato automaticamente prima di restituire l'arresto anomalo dell'applicazione, in caso contrario, gli oggetti vengono semplicemente trapelati.

Qualsiasi luce che potrebbe essere versata su questo sarebbe molto apprezzata.

Nota: stringByEncodingURLEntities è un metodo di categoria su 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 

UPDATE: Dopo aver inviato un radar ad Apple sembra che questo è un problema noto (Radar # 7.640.470).

+0

Sei sicuro che siano trapelate se non sono autorizzate? E sei sicuro che il tuo programma si blocca perché provi a rilasciarli? Le regole di gestione della memoria affermano chiaramente che saresti tu il responsabile del rilascio di quell'oggetto. – zneak

+3

Sì, stanno perdendo definitivamente se non sono autorizzate. Il programma si arresta in modo anomalo perché viene inviato un messaggio di conservazione a un oggetto deallocato –

risposta

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

Beh, questo non è un alloc, new o copy metodo ...

... e CSURLCache non tiene sul all'oggetto da nessuna parte, quindi non è possederlo.

Quindi, è necessario autorizzarlo automaticamente.

Ovviamente, ciò significa che l'oggetto è condannato a meno che qualcosa non lo mantenga. La tua app si è bloccata perché ha tentato di utilizzare l'oggetto dopo la morte dell'oggetto.

Esegui la tua app sotto Strumenti con il modello Zombi. Guarda dove l'app si è bloccata e cosa stava facendo quando è stato chiamato cachedResponseForRequest:. Il chiamante deve possedere l'oggetto fino al momento in cui l'applicazione si arresta in modo anomalo, quindi rilasciarlo.

+0

L'app si arresta in modo anomalo perché viene inviato un messaggio di conservazione a un oggetto deallocato, tuttavia, con un'indagine successiva, NOT cachedResponse. Non riesco comunque a capire a quale oggetto viene inviato il messaggio. Se abilito NSZombieEnabled, stampa "[Non conservare un tipo]". –

+0

Non credete che questa sia la soluzione, dato che NSCachedResponse non è l'oggetto che causa l'arresto anomalo quando viene rilasciato (si blocca come parte del suo dealloc, il che significa che qualcosa che NSCachedResponse sta mantenendo non è in esecuzione) – BadPirate

+0

outtru.mp : Implementare correttamente la gestione della memoria non è facoltativo (non farlo significherebbe che l'interrogante avrebbe due bug), e lo strumento Zombies è il modo in cui si determinerà quale oggetto è sovrascritto e quale è stata la versione estranea. Quindi, l'aspetto precedente è parte della soluzione (la perdita potrebbe essere preferibile a un arresto anomalo, ma una volta eliminato il crash, anche la perdita dovrebbe esserlo), e quest'ultima è parte dell'indagine sul problema reale. –