NSURLCache 会因自动释放的对象而崩溃,但否则会泄漏

发布于 2024-08-20 01:18:30 字数 1482 浏览 8 评论 0原文

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)。

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吖咩 2024-08-27 01:18:31
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)请求

嗯,这不是一个 allocnewcopy 方法……

并且 CSURLCache 不会在任何地方保留该对象,所以它不拥有它。

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

当然,这意味着除非有东西保留它,否则该物体注定会失败。您的应用程序崩溃了,因为它在对象死亡后尝试使用该对象。

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

- (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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文