我在 iOS(5.1、6.0、6.1)上遇到了一个令人不安的 NSURLConnection 问题。
当我尝试通过 http 请求下载大部分数据时,我的应用程序不会将已发布的数据标记为真正已发布(我将在稍后解释)。
我的下载代码如下所示:
NSURL *url = [NSURL URLWithString:@"http://my.server/file.zip"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[urlConnection start];
委托(delegate)是我的 View Controller 。
此代码在主运行循环上调用(没有调度队列或执行选择器之类的东西)。
委托(delegate)对接收到的数据绝对不做任何事情——不保留,不复制——什么都不做。
问题是,当我用新创建的项目调用此代码时 - 它表现良好 - 下载所有数据并顺利完成。
但是当在我的其他应用程序中调用代码时,突然所有下载的数据都会在应用程序中留下内存占用空间,一段时间后内存耗尽,应用程序收到内存警告并崩溃。
您可能会说 - 您的委托(delegate)保留数据但不发布它。好吧,我试图用 Instruments 找到解决方案。你猜怎么着 - 我的应用程序在分配时显示它在下载资源时保留了大约 10 mb 的内存! Allocations 或 VM Tracker 上没有显示任何内容。
那么我怎么知道应用程序保留了下载数据的内存占用空间?
这是向我展示我的内存报告的代码(早些时候在这个网站的一些答案中找到它 - 虽然现在找不到它:
-(void) report_memory {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&info,
&size);
if( kerr == KERN_SUCCESS ) {
STLog(ST_DEBUG, @"Memory in use (in bytes): %u b ( %u mb )", info.resident_size, info.resident_size / (1024 * 1024) );
} else {
STLog(ST_DEBUG, @"Error with task_info(): %s", mach_error_string(kerr));
}
}
我的问题是 - 这里发生了什么?
为什么应用会显示一些内存占用?
为什么工具没有显示过度分配?
NSURLConnection 过度分配的原因是什么?
附言。我还尝试更改磁盘、内存中的共享缓存大小,使用其他缓存策略 - 没有任何帮助:(
最佳答案
事实证明,当使用僵尸对象时,NSURLConnection 会保留已释放的对象。这会阻止它们完全释放 - 因此会占用内存。
解决方案是在通过 NSURLConnection 下载大部分数据时不要使用僵尸对象。
关于ios - NSURLConnection 在下载大部分数据时导致内存警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14752121/