NSURLConnection弄乱了iPad的内存 [英] NSURLConnection messes up iPad memory

查看:79
本文介绍了NSURLConnection弄乱了iPad的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们构建了一个iPad应用程序,该应用程序从Web服务下载大量数据和PDF文档(首先是数据,然后是后台文件).为此,我们通过HTTP(S)请求使用SOAP.它可以正常运行,并且该应用程序运行良好.问题是,如果某个时刻有太多文档无法下载,则应用程序崩溃.使用仪器,我发现这是一个内存问题,尤其是NSRegularExpression和NSRunLoop. (我正在使用ARC)

we build an iPad app that downloads a bunch of data and PDF documents from a web service (data first, documents later in the background). To do so, we use SOAP via HTTP(S) requests. It works fine and altogether, the app is running well. Problem is, if there are too many documents to download at some point the app crashes. Using Instruments I figured out that it is a memory issue, particularly NSRegularExpression and NSRunLoop. (I'm using ARC)

我可以改进代码以优化NSRegularExpression的创建.但是我不知道如何改善NSRunLoop问题.

I could improve my code to optimize the NSRegularExpression creation. But I don't know how to improve the NSRunLoop issue.

我尝试了异步和同步HTTP请求.使用异步,我不得不等待下载完成,并且由于sleep()/[NSThread sleepForTimeInterval:]不是一个选项,所以我使用

I tried both, asynchronous and synchronous HTTP request. Using async, I had to wait for the download to finish and since sleep()/[NSThread sleepForTimeInterval:] aren't an option, I use

while ( _waitToFinish ) {
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

使用同步请求,Instruments会显示

Using sync request, Instruments reveals that

[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];

在NSRunLoop的帮助下也等待"并且还弄乱了内存.

also "waits" with help of NSRunLoop and also messes up the memory.

这是CoreFoundation或ARC中的错误吗?

Is this a bug in CoreFoundation or ARC?

在等待请求完成时还有另一种空闲方式吗?

Is there another way to idle while waiting for the requests to finish?

谢谢.

对于内存问题",我的意思是该应用程序崩溃(或被iOS杀死),因为它使用了过多的内存.

With "memory issue" I meant that the app crashes (or is killed by iOS) because it uses too much memory.

这是仪器显示的内容: 应用下载的时间越长,百分比就越高.

This is what Instruments shows: The percentage get higher the longer the app is downloading.

进一步往下看,它是NSURLConnection,它使内存混乱.似乎我以某种方式错过了将connectionreceivedData设置为nil的方法(请参阅

Going further down revealed that it is NSURLConnection, that is messing up the memory. It seems that I have somehow missed setting connection and receivedData to nil (see URL Loading System Programming Guide). This improved my memory usage again a little.

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

Now, there are two more big memory allocation operations:

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

And this is the code I think belongs to what Instruments displays:

-(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;
}

有什么我需要更改以改进代码的地方吗?

Is there anything I could change to improve the code?

编辑 :(标题从"NSRunLoop改变了iPad的内存")

(Changed title from "NSRunLoop messes up iPad memory")

修改: 我创建了一个测试应用程序,以证明是NSURLConnection弄乱了内存.然后,我联系了Apple开发人员支持.

I created a test app to prove that it is the NSURLConnection, that messes up the memory. Then I contacted the Apple Developer Support.

由于我要使用NSURLConnection进行迭代下载大量PDF,因此解决方案是在迭代中添加@autoreleasepool { .. }并在NSRunLoop周围添加另一个.

Since I am downloading a lot of PDF in an iteration with NSURLConnection, the solution was to add an @autoreleasepool { .. } in the iteration and another one around the NSRunLoop.

谢谢.

推荐答案

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

It's not a bug in Core Foundation or ARC. It's a bug in your code.

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

Don't run the run loop yourself. Just use +[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]. It will call your completionHandler block when the request is complete. That's when you process the response. Meanwhile, just return out of your method and let the system worry about running the run loop.

您用NSRegularExpressionNSRunLoop说这是一个内存问题",但您没有说出问题是什么,或者是Instruments向您显示的证据.如果您更详细地描述问题",也许我们可以为您提供帮助.

You say "it's a memory issue" with NSRegularExpression and NSRunLoop, but you don't say what the issue is, or what evidence Instruments is showing you. If you describe the "issue" in more detail, maybe we can help you with that.

这篇关于NSURLConnection弄乱了iPad的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆