【发布时间】:2012-03-19 17:17:34
【问题描述】:
我们构建了一个 iPad 应用程序,它从 Web 服务下载大量数据和 PDF 文档(首先是数据,然后是后台的文档)。为此,我们通过 HTTP(S) 请求使用 SOAP。它运行良好,总体而言,该应用程序运行良好。问题是,如果在某个时候要下载的文档太多,应用程序就会崩溃。使用 Instruments 我发现这是一个内存问题,尤其是 NSRegularExpression 和 NSRunLoop。 (我正在使用 ARC)
我可以改进我的代码来优化 NSRegularExpression 创建。但我不知道如何改进 NSRunLoop 问题。
我尝试了异步和同步 HTTP 请求。使用异步,我不得不等待下载完成,因为 sleep()/[NSThread sleepForTimeInterval:] 不是一个选项,我使用
while ( _waitToFinish ) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
使用同步请求,Instruments 显示
[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];
在 NSRunLoop 的帮助下也会“等待”,也会弄乱内存。
这是 CoreFoundation 或 ARC 中的错误吗?
在等待请求完成时还有其他空闲方式吗?
提前致谢。
编辑:
“内存问题”是指应用程序崩溃(或被 iOS 杀死),因为它使用了太多内存。
这是 Instruments 显示的: 应用下载的时间越长,百分比越高。
编辑:
再往下看,发现是 NSURLConnection 搞砸了内存。似乎我以某种方式错过了将connection 和receivedData 设置为nil(参见URL Loading System Programming Guide)。这再次提高了我的内存使用率。
现在,还有两个更大的内存分配操作:
这是我认为属于 Instruments 显示的代码:
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_receivedData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseText = [[NSString alloc] initWithBytes:[_receivedData mutableBytes] length:[_receivedData length] encoding:NSUTF8StringEncoding];
self.lastResponse = responseText;
responseText = nil;
connection = nil;
_receivedData = nil;
_lastResult = TRUE;
_waitToFinish = FALSE;
}
有什么我可以改变来改进代码的吗?
编辑:(将标题从“NSRunLoop 搞乱了 iPad 内存”)
编辑: 我创建了一个测试应用程序来证明是 NSURLConnection 搞砸了内存。然后我联系了 Apple Developer Support。
由于我在迭代中使用 NSURLConnection 下载了大量 PDF,因此解决方案是在迭代中添加一个 @autoreleasepool { .. },并在 NSRunLoop 周围添加另一个。
谢谢。
【问题讨论】:
-
CFRunLoopRunInMode本身可能并没有真正分配太多内存。它只是等待事件,然后调用已注册的函数来处理这些事件。您需要在该大纲视图中进一步深入了解到底是什么在分配内存。
标签: objective-c ipad memory-leaks nsurlconnection nsrunloop