NSURLCache 会因自动释放的对象而崩溃,但否则会泄漏
CSURLCache
旨在缓存离线浏览的资源,因为 NSURLCache
仅将数据存储在内存中。
如果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
更新:向 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,这不是一个
alloc
、new
或copy
方法……并且 CSURLCache 不会在任何地方保留该对象,所以它不拥有它。
所以,你需要自动释放它。
当然,这意味着除非有东西保留它,否则该物体注定会失败。您的应用程序崩溃了,因为它在对象死亡后尝试使用该对象。
使用 Zombies 模板在 Instruments 下运行您的应用程序。查看应用程序崩溃的位置以及调用
cachedResponseForRequest:
时它正在执行的操作。调用者需要拥有该对象,直到应用程序崩溃为止,然后释放它。Well, this isn't an
alloc
,new
, orcopy
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.