'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

时间:2022-12-09 08:58:47

My code is the following:

我的代码如下:

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

There is nothing special at all. I am not even using the background thread.

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

Here is the behavior I get on iOS 8.x (and the behavior that I expect to get):

这是我在ios8上的行为。x(以及我期望得到的行为):

'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

So, NSData is fully released and all of the occupied memory is back.

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

However, iOS 9.x surprised me a lot:

然而,iOS 9。x让我非常吃惊:

'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

My questions are:

我的问题是:

  1. Approximately 100 MB are gone for nothing in iOS 9.x. How can I get them back? Are there any workarounds?

    在ios9 .x中,大约100 MB的内存都没有了。我怎样才能把它们找回来呢?有什么解决方法吗?

  2. iOS 8.x has occupied 136.2 MB at max, while iOS 9.x used 225.9 MB at max. Why is this happening?

    iOS 8。x在max上占用了136.2 MB,而iOS 9。x最大使用225.9 MB。为什么会这样?

  3. What is going on in iOS 9.x?

    iOS 9。x里发生了什么?

UPDATE #1:

I have also tried using NSURLSession 'dataTaskWithURL:completionHandler:' (thanks to @CouchDeveloper). This reduces the leak, but doesn't fully solve the problem (this time both iOS 8.x and iOS 9.x).

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

I used the code below:

我使用下面的代码:

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];

'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

As you can see, 30 MB are still lost.

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

UPDATE #2:

The above tests where done using Xcode simulator.

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

However, I have also decided to test on actual iOS 9.2 iPhone 4S (as recommended by @Sohil R. Memon).

然而,我也决定在ios9.2 iPhone 4S上进行测试(@Sohil R. Memon推荐)。

The results of 'NSData dataWithContentsOfURL:' are below:

NSData dataWithContentsOfURL的结果如下:

'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

The results of using 'NSURLSession dataTaskWithURL:completionHandler:' are below:

使用“NSURLSession dataTaskWithURL:completionHandler:”的结果如下:

'NSData dataWithContentsOfURL:'内存泄漏ios9.x ?

It looks like 'NSData dataWithContentsOfURL:' works perfectly on actual device, while 'NSURLSession dataTaskWithURL:completionHandler:' -- doesn't.

看起来“NSData dataWithContentsOfURL:”在实际设备上运行得很好,而“NSURLSession dataTaskWithURL:completionHandler:”则不行。

However, does anyone know solutions which show identical information on BOTH actual device AND Xcode simulator?

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

2 个解决方案

#1


4  

Approximately 100 MB are gone for nothing in iOS 9.x. How can I get them back? Are there any workarounds?

在ios9 .x中,大约100 MB的内存都没有了。我怎样才能把它们找回来呢?有什么解决方法吗?

For a couple of reasons, we should use NSURLSession to download data from a web service. So, this is not a workaround, but the correct approach.

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

What is going on in iOS 9.x?

iOS 9。x里发生了什么?

I have no idea - possibly cached data, network buffers, or some other issues. But this is irrelevant - you should try the correct approach with NSURLSession.

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

From the docs:

从文档:

IMPORTANT

重要的

Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated.

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

Instead, for non-file URLs, consider using the dataTaskWithURL:completionHandler: method of the NSURLSession class. See URL Session Programming Guide for details.

相反,对于非文件url,可以考虑使用dataTaskWithURL:completionHandler: NSURLSession类的方法。有关详细信息,请参阅URL会话编程指南。

Edit:

编辑:

Those "reasons" are:

这些“理由”是:

  • NSURLSession is specifically designed to load remote resources.

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

  • NSURLSession methods are asynchronous which is crucial for methods which complete only after a perceivable duration (it will not block the calling thread).

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

  • A session can handle authentication by means of a default method or with a custom delegate.

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

  • Session tasks can be cancelled.

    会话任务可以取消。

#2


1  

Here is also an answer which helped me. The answer states to use [NSData dataWithContentsOfURL:url options:0 error:&error]; instead.

这也是一个对我有帮助的答案。答案说明使用[NSData dataWithContentsOfURL:url选项:0 error:&error];代替。

Hope this helps

希望这有助于

#1


4  

Approximately 100 MB are gone for nothing in iOS 9.x. How can I get them back? Are there any workarounds?

在ios9 .x中,大约100 MB的内存都没有了。我怎样才能把它们找回来呢?有什么解决方法吗?

For a couple of reasons, we should use NSURLSession to download data from a web service. So, this is not a workaround, but the correct approach.

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

What is going on in iOS 9.x?

iOS 9。x里发生了什么?

I have no idea - possibly cached data, network buffers, or some other issues. But this is irrelevant - you should try the correct approach with NSURLSession.

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

From the docs:

从文档:

IMPORTANT

重要的

Do not use this synchronous method to request network-based URLs. For network-based URLs, this method can block the current thread for tens of seconds on a slow network, resulting in a poor user experience, and in iOS, may cause your app to be terminated.

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

Instead, for non-file URLs, consider using the dataTaskWithURL:completionHandler: method of the NSURLSession class. See URL Session Programming Guide for details.

相反,对于非文件url,可以考虑使用dataTaskWithURL:completionHandler: NSURLSession类的方法。有关详细信息,请参阅URL会话编程指南。

Edit:

编辑:

Those "reasons" are:

这些“理由”是:

  • NSURLSession is specifically designed to load remote resources.

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

  • NSURLSession methods are asynchronous which is crucial for methods which complete only after a perceivable duration (it will not block the calling thread).

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

  • A session can handle authentication by means of a default method or with a custom delegate.

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

  • Session tasks can be cancelled.

    会话任务可以取消。

#2


1  

Here is also an answer which helped me. The answer states to use [NSData dataWithContentsOfURL:url options:0 error:&error]; instead.

这也是一个对我有帮助的答案。答案说明使用[NSData dataWithContentsOfURL:url选项:0 error:&error];代替。

Hope this helps

希望这有助于