2

我们构建了一个 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 搞砸了内存。似乎我以某种方式错过了设置connectionreceivedData设置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.

谢谢。

4

1 回答 1

1

这不是 Core Foundation 或 ARC 中的错误。这是您的代码中的错误。

不要自己运行运行循环。只需使用+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]. completionHandler请求完成后,它将调用您的块。那是您处理响应的时候。同时,只需退出您的方法并让系统担心运行运行循环。

NSRegularExpression你用and说“这是一个记忆问题” NSRunLoop,但你没有说问题是什么,或者 Instruments 向你展示了什么证据。如果您更详细地描述“问题”,也许我们可以帮助您。

于 2012-03-01T07:55:48.580 回答