NSURLConnection搞砸了iPad内存

时间:2012-03-01 07:41:00

标签: objective-c ipad memory-leaks nsurlconnection nsrunloop

我们构建了一个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杀死),因为它占用了太多内存。

这是仪器显示的: Instruments screenshot 应用程序下载的时间越长,百分比越高。

修改

进一步向下透露,这是NSURLConnection,这是弄乱了记忆。我似乎错过了设置connectionreceivedDatanil的设置(请参阅URL Loading System Programming Guide)。这再次提高了我的内存使用率。

现在,还有两个更大的内存分配操作: enter image description here

这是我认为属于仪器显示的代码:

-(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周围添加另一个。

感谢。

1 个答案:

答案 0 :(得分:1)

这不是Core Foundation或ARC中的错误。这是你代码中的一个错误。

不要自己运行run loop。只需使用+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]即可。它会在请求完成后调用您的completionHandler块。那是你处理响应的时候。同时,只需返回您的方法,让系统担心运行运行循环。

您使用NSRegularExpressionNSRunLoop说“这是一个内存问题”,但您没有说明问题是什么,或者仪器向您展示了哪些证据。如果您更详细地描述“问题”,也许我们可以帮助您。