首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“NSData dataWithContentsOfURL:”内存泄漏iOS 9.x?

“NSData dataWithContentsOfURL:”内存泄漏iOS 9.x?
EN

Stack Overflow用户
提问于 2015-12-28 12:10:16
回答 2查看 697关注 0票数 3

我的代码如下:

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

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

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

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

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

我的问题是:

  1. 在iOS 9.x中大约有100 MB是免费的。我怎么才能把它们拿回来?有什么解决办法吗?
  2. iOS 8.x最大占用136.2 MB,而iOS 9.x最大占用225.9 MB。为什么会发生这种情况?
  3. iOS 9.x是怎么回事?

更新#1:

我还尝试使用NSURLSession 'dataTaskWithURL:completionHandler:‘(感谢@CouchDeveloper)。这减少了泄漏,但没有完全解决问题(这次是iOS 8.x和iOS 9.x)。

我使用了以下代码:

代码语言:javascript
复制
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];

如您所见,仍有30 MB的内存丢失。

更新2:

上面的测试是用Xcode模拟器完成的。

不过,我还决定在实际的iOS 9.2 iPhone 4S上进行测试(正如@Sohil R. Memon所推荐的那样)。

“NSData dataWithContentsOfURL:”的结果如下:

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

它看起来像'NSData dataWithContentsOfURL:‘在实际的设备上工作得很好,而'NSURLSession dataTaskWithURL:completionHandler:’-没有。

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

EN

回答 2

Stack Overflow用户

发布于 2015-12-28 15:22:45

在iOS 9.x中大约有100 MB是免费的。我怎么才能把它们拿回来?有什么解决办法吗?

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

iOS 9.x是怎么回事?

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

来自文档

重要

不要使用此同步方法请求基于网络的URL。对于基于网络的URL,这种方法可以在一个缓慢的网络上阻塞当前线程几十秒,导致用户体验差,在iOS中,可能会导致应用程序被终止。

相反,对于非文件URL,请考虑使用NSURLSession类的NSURLSession方法。详情请参见URL会话编程指南

编辑:

这些“理由”是:

  • NSURLSession是专门设计用来加载远程资源的。
  • NSURLSession方法是异步的,这对于只在可感知的持续时间之后才完成的方法(它不会阻塞调用线程)至关重要。
  • 会话可以通过默认方法或使用自定义委托来处理身份验证。
  • 可以取消会话任务。
票数 4
EN

Stack Overflow用户

发布于 2015-12-28 12:13:13

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

希望这能有所帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34493306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档