NSURLCache crashes with autoreleased objects, but leaks otherwise
CSURLCache
is designed to cache resources for offline browsing, as NSURLCache
only stores data in-memory.
If cachedResponse
is autoreleased before returning the application crashes, if not, the objects are simply leaked.
Any light that could be shed onto this would be much appreciated.
Please note stringByEncodingURLEntities
is a category method on 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:[r开发者_StackOverflowequest 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: After submitting a radar to Apple it appears that this is a known issue (Radar #7640470).
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request
Well, this isn't an alloc
, new
, or copy
method…
… and CSURLCache doesn't hold on to the object anywhere, so it's not owning it.
So, you need to autorelease it.
Of course, that means the object is doomed unless something retains it. Your app crashed because it tried to use the object after the object died.
Run your app under Instruments with the Zombies template. Look at where the app crashes and what it was doing when cachedResponseForRequest:
was called. The caller needs to own the object until the time when the application would crash otherwise, and then release it.
精彩评论