我们构建了一个 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 中的错误吗?
在等待请求完成时还有其他方法可以空闲吗?
提前致谢。
Edit:
对于“内存问题”,我的意思是应用程序崩溃(或被 iOS 杀死),因为它使用了太多内存。
This is what Instruments shows:
The percentage get higher the longer the app is downloading.
Edit:
再往下看,发现是 NSURLConnection,它搞乱了内存。看来我错过了设置connection
and receivedData
to nil
(see URL加载系统编程指南 https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html)。这又稍微改善了我的内存使用情况。
Now, there are two more big memory allocation operations:
这是我认为属于 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;
}
我可以改变什么来改进代码吗?
Edit:(更改标题“NSRunLoop 弄乱 iPad 内存”)
Edit:我创建了一个测试应用程序来证明是 NSURLConnection 搞乱了内存。然后我联系了苹果开发者支持。
由于我在使用 NSURLConnection 的迭代中下载了大量 PDF,因此解决方案是添加@autoreleasepool { .. }
在迭代中和围绕NSRunLoop
.
Thanks.