'NSData dataWithContentsOfURL:'内存泄漏iOS 9.x?

时间:2015-12-28 12:10:16

标签: ios objective-c xcode memory nsdata

我的代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *theURLString = @"http://website.com/musicFile";
    NSData *theData = [NSData dataWithContentsOfURL:[NSURL URLWithString:theURLString]];
}

没有什么特别的。我甚至没有使用后台线程。

以下是我在iOS 8.x上获得的行为(以及我希望获得的行为):

enter image description here

因此,NSData完全释放,所有占用的内存都回来了。

然而,iOS 9.x让我大吃一惊:

enter image description here

我的问题是:

  1. 在iOS 9.x中,大约100 MB没有任何效果。我怎样才能让他们回来?有没有解决方法?

  2. iOS 8.x最多占用136.2 MB,而iOS 9.x最大使用225.9 MB。为什么会这样?

  3. iOS 9.x中发生了什么?

  4. 更新#1:

    我也尝试过使用NSURLSession'dataTaskWithURL:completionHandler:'(感谢@CouchDeveloper)。这样可以减少泄漏,但不能完全解决问题(这次是iOS 8.x和iOS 9.x)。

    我使用了以下代码:

    NSURLSession *theURLSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSURLSessionDataTask *theURLSessionDataTask = [theURLSession dataTaskWithURL:[NSURL URLWithString:theURLString]
                                                                   completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
                                                       {
                                                           NSLog(@"done");
                                                       }];
    [theURLSessionDataTask resume];
    

    enter image description here

    如您所见,30 MB仍然丢失。

    更新#2:

    以上测试使用Xcode模拟器完成。

    然而,我还决定测试实际的iOS 9.2 iPhone 4S(由@Sohil R. Memon推荐)。

    'NSData dataWithContentsOfURL:'的结果如下:

    enter image description here

    使用'NSURLSession dataTaskWithURL:completionHandler:'的结果如下:

    enter image description here

    看起来像'NSData dataWithContentsOfURL:'在实际设备上完美运行,而'NSURLSession dataTaskWithURL:completionHandler:' - 没有。

    但是,有没有人知道在实际设备和Xcode模拟器上显示相同信息的解决方案?

2 个答案:

答案 0 :(得分:4)

  

在iOS 9.x中大约100 MB无效。我怎样才能让他们回来?有没有解决方法?

由于几个原因,我们应该使用NSURLSession从Web服务下载数据。所以,这不是一种解决方法,而是正确的方法。

  

iOS 9.x中发生了什么?

我不知道 - 可能是缓存数据,网络缓冲区或其他一些问题。但这是无关紧要的 - 您应该使用NSURLSession尝试正确的方法。

来自docs

重要

请勿使用此同步方法来请求基于网络的网址。对于基于网络的URL,此方法可以在慢速网络上阻止当前线程持续数十秒,从而导致用户体验不佳,而在iOS中,可能会导致应用程序被终止。

相反,对于非文件网址,请考虑使用dataTaskWithURL:completionHandler:类的NSURLSession方法。有关详细信息,请参阅URL Session Programming Guide

修改

那些"原因"是:

  • NSURLSession专门用于加载远程资源。

  • NSURLSession方法是异步,这对于仅在可感知的持续时间之后完成的方法至关重要(它不会阻塞调用线程)。

  • 会话可以通过默认方法或自定义委托来处理身份验证。

  • 可以取消会话任务。

答案 1 :(得分:1)

Here也是一个帮助我的答案。答案表明使用[NSData dataWithContentsOfURL:url options:0 error:&error];代替。

希望这有帮助