开发者

NSURLCache crashes with autoreleased objects, but leaks otherwise

开发者 https://www.devze.com 2022-12-18 05:35 出处:网络
CSURLCache is designed to cache resources for offline browsing, as NSURLCache only stores data in-memory.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消