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(以及我期望得到的行为):
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让我非常吃惊:
My questions are:
我的问题是:
-
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的内存都没有了。我怎样才能把它们找回来呢?有什么解决方法吗?
-
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。为什么会这样?
-
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];
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的结果如下:
The results of using 'NSURLSession dataTaskWithURL:completionHandler:' are below:
使用“NSURLSession dataTaskWithURL:completionHandler:”的结果如下:
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
希望这有助于