我们构建了一个iPad应用程序,可以从Web服务下载大量数据和PDF文档(数据优先,后面的文档在后台)。为此,我们通过HTTP(S)请求使用SOAP。它运行良好,并且应用程序运行良好。问题是,如果在某些时候有太多文件需要下载,应用程序崩溃了。使用Instruments我发现它是一个内存问题,特别是NSRegularExpression和NSRunLoop。 (我正在使用ARC)
我可以改进我的代码来优化NSRegularExpression的创建。但我不知道如何改善NSRunLoop问题。
我尝试了异步和同步HTTP请求。使用async,我不得不等待下载完成,因为sleep()/ [NSThread sleepForTimeInterval:]不是一个选项,我使用
while ( _waitToFinish ) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
使用同步请求,仪器显示
[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];
还在NSRunLoop的帮助下“等待”并且还会弄乱记忆。
这是CoreFoundation或ARC中的错误吗?
在等待请求完成时是否还有另一种闲置方式?
提前致谢。
修改
对于“内存问题”,我的意思是应用程序崩溃(或被iOS杀死),因为它占用了太多内存。
这是仪器显示的: 应用程序下载的时间越长,百分比越高。
修改
进一步向下透露,这是NSURLConnection,这是弄乱了记忆。我似乎错过了设置connection
和receivedData
到nil
的设置(请参阅URL Loading System Programming Guide)。这再次提高了我的内存使用率。
现在,还有两个更大的内存分配操作:
这是我认为属于仪器显示的代码:
-(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
周围添加另一个。
感谢。
答案 0 :(得分:1)
这不是Core Foundation或ARC中的错误。这是你代码中的一个错误。
不要自己运行run loop。只需使用+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
即可。它会在请求完成后调用您的completionHandler
块。那是你处理响应的时候。同时,只需返回您的方法,让系统担心运行运行循环。
您使用NSRegularExpression
和NSRunLoop
说“这是一个内存问题”,但您没有说明问题是什么,或者仪器向您展示了哪些证据。如果您更详细地描述“问题”,也许我们可以帮助您。