我们构建了一个 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 加载系统编程指南)。这再次提高了我的内存使用率。
现在,还有两个更大的内存分配操作:
这是我认为属于 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,它弄乱了内存。然后我联系了苹果开发者支持。
由于我在使用 NSURLConnection 的迭代中下载了大量 PDF,因此解决方案是@autoreleasepool { .. }
在迭代中添加一个,在NSRunLoop
.
谢谢。