【问题标题】:NSURLCache crashes with autoreleased objects, but leaks otherwiseNSURLCache 与自动释放的对象一起崩溃,否则会泄漏
【发布时间】:2011-01-10 16:19:13
【问题描述】:

CSURLCache 旨在缓存资源以供离线浏览,因为NSURLCache 仅将数据存储在内存中。

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

我们将不胜感激。

请注意stringByEncodingURLEntitiesNSString上的分类方法。

@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

更新:在向 Apple 提交雷达后,这似乎是一个已知问题 (Radar #7640470)。

【问题讨论】:

  • 如果它们没有自动发布,你确定它们会被泄露吗?你确定你的程序崩溃是因为你试图释放它们吗?内存管理规则明确规定您将负责释放该对象。
  • 是的,如果不自动发布,它们肯定会泄漏。程序崩溃,因为保留消息被发送到一个释放的对象

标签: objective-c cocoa autorelease nsurlcache


【解决方案1】:
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request

嗯,这不是 allocnewcopy 方法……

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

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

当然,这意味着该对象注定要失败,除非有什么东西保留它。您的应用崩溃了,因为它在对象死亡后尝试使用该对象。

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

【讨论】:

  • 应用程序崩溃,因为保留消息被发送到一个已释放的对象,但是,在随后的调查中,不是缓存的响应。但是,我无法弄清楚正在向哪个对象发送消息。如果我启用 NSZombieEnabled,它会打印“[Not A Type retain]”。
  • 不要相信这是解决方案,因为 NSCachedResponse 不是在释放时导致崩溃的对象(它作为其 dealloc 的一部分而崩溃,这意味着 NSCachedResponse 保留的东西已过度发布)
  • outtru.mp:正确实施内存管理不是可选的(不这样做意味着提问者会有两个错误),僵尸工具是您如何确定哪些对象被过度释放和无关的释放是什么。所以,前一个方面是解决方案的一部分(泄漏可能比崩溃更可取,但一旦崩溃被消除,泄漏也应该是),后者是真正问题调查的一部分。
猜你喜欢
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2011-03-09
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2012-06-13
相关资源
最近更新 更多