2010-01-29 3 views
5

CSURLCache dient zum Zwischenspeichern von Ressourcen für das Offline-Browsing, da NSURLCache nur Daten in Arbeitsspeicher speichert.NSURLCache stürzt mit autoreleased Objekten ab, aber Lecks sonst

Wenn cachedResponse wird automatisch freigegeben, bevor die Anwendung abstürzt, wenn nicht, die Objekte sind einfach undicht.

Jedes Licht, das sich darauf werfen könnte, würde sehr geschätzt werden.

Bitte beachten Sie stringByEncodingURLEntities ist eine Kategorie-Methode auf 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: Nachdem ein Radar an Apple einreichen scheint es, dass dies ein bekanntes Problem ist (Radar # 7640470).

+0

Sind Sie sicher, dass sie durchgesickert sind, wenn sie nicht automatisch freigegeben wurden? Und bist du sicher, dass dein Programm abstürzt, weil du versuchst, sie zu veröffentlichen? Speicherverwaltungsregeln geben eindeutig an, dass Sie derjenige sein würden, der für die Freigabe dieses Objekts verantwortlich ist. – zneak

+3

Ja, sie sind definitiv undicht, wenn nicht automatisch freigegeben. Das Programm stürzt ab, weil eine Retain-Nachricht an ein nicht zugeordnetes Objekt gesendet wird –

Antwort

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

Nun, das ist keine alloc, new oder copy Methode ...

... und CSURLCache überall auf das Objekt nicht festhalten, so dass er es nicht ist zu besitzen.

Also müssen Sie es automatisch freigeben.

Natürlich bedeutet das, dass das Objekt zum Scheitern verurteilt ist, es sei denn, etwas behält es bei. Ihre App ist abgestürzt, weil sie versucht hat, das Objekt nach dem Tod des Objekts zu verwenden.

Führen Sie Ihre App unter Instrumente mit der Zombies-Vorlage. Schau dir an, wo die App abstürzt und was sie macht, als cachedResponseForRequest: aufgerufen wurde. Der Aufrufer muss das Objekt bis zu dem Zeitpunkt besitzen, zu dem die Anwendung andernfalls abstürzen würde, und es dann freigeben.

+0

Die App stürzt ab, weil eine Retain-Nachricht an ein nicht zugeordnetes Objekt gesendet wird. Bei der nachfolgenden Untersuchung wird jedoch NICHT die cachedResponse-Nachricht zurückgegeben. Ich kann jedoch nicht herausfinden, welches Objekt die Nachricht gesendet wird. Wenn ich NSZombieEnabled aktiviere, wird "[Kein Typ beibehalten]" gedruckt. –

+0

Glauben Sie nicht, dass dies die Lösung ist, da die NSCachedResponse nicht das Objekt ist, das den Absturz verursacht, wenn es freigegeben wird (es stürzt ab, weil es dealloc ist, was bedeutet, dass NSCachedResponse überveröffentlicht ist) – BadPirate

+0

outtru.mp : Das korrekte Implementieren der Speicherverwaltung ist nicht optional (andernfalls würde der Frager zwei Bugs haben), und mit dem Zombies-Instrument bestimmen Sie, welches Objekt zu viel freigegeben wurde und was die externe Veröffentlichung war. Daher ist der erstgenannte Aspekt Teil der Lösung (Leckage ist vielleicht besser als ein Crash, aber sobald der Crash beseitigt ist, sollte das Leck auch sein), und Letzteres ist Teil der Untersuchung des wirklichen Problems. –