NSURLCache与自动释放的对象崩溃,但泄漏否则 [英] NSURLCache crashes with autoreleased objects, but leaks otherwise

查看:373
本文介绍了NSURLCache与自动释放的对象崩溃,但泄漏否则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

CSURLCache 用于缓存离线浏览的资源,因为 NSURLCache 只存储内存中的数据。 p>

如果 cachedResponse 在返回应用程序崩溃之前自动释放,如果没有,对象就会被泄露。

$



请注意 stringByEncodingURLEntities 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 :向苹果提交雷达后,看来这是一个已知问题(雷达#7640470)。

解决方案


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


< blockquote>

好吧,这不是一个 alloc new copy 方法...



...并且CSURLCache不会在任何地方持有对象,因此它不拥有它。



所以,你需要自动释放它。



当然,这意味着对象注定保留它。您的应用程式崩溃,因为它试图在对象死后使用对象。



使用Zombies模板运行您的应用程序。查看应用程序崩溃的位置,以及调用 cachedResponseForRequest:时的操作。调用者需要拥有对象,直到应用程序崩溃,然后释放它。


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:[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: 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.

这篇关于NSURLCache与自动释放的对象崩溃,但泄漏否则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆