NSURLSession 的内存泄漏
memory leak for NSURLSession
在 xcode 仪器中,我遇到此方法内存泄漏
- (void)getDataForRequest:(NSURLRequest *)request completionHandler:(downloadCompletionBlock)completionHandler
{
self.expectedLength = 0;
self.currentLength = 0;
self.responseData = Nil;
self.contentLengthBlock = nil;
self.completionBlock = completionHandler;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
self.postDataTask = [session dataTaskWithRequest:request];
[self.postDataTask resume];
}
问题可能出在短语 delegate: self
上。 NSURLSession 保留其委托。因此,您告诉会话保留此实例(可能是视图控制器)。在您使会话无效之前,视图控制器不会消失。
解决方法是:正确管理会话。保留对会话的引用,以便稍后可以使它无效。更好的是,使委托成为轻量级对象,不同于视图控制器,您可以管理其内存。
此代码段中的一个问题是您正在为每个请求创建一个新的 NSURLSession
,并且您永远不会使会话无效。如果发起请求后调用finishTasksAndInvalidate
,则:
- 请求完成后,回收与
NSURLSession
关联的内存;通过这样做,它也将
- 释放对
delegate
对象的强引用。
因此:
- (void)getDataForRequest:(NSURLRequest *)request completionHandler:(DownloadCompletionBlock)completionHandler {
self.expectedLength = 0;
self.currentLength = 0;
self.responseData = nil;
self.contentLengthBlock = nil;
self.completionBlock = completionHandler;
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:[NSOperationQueue mainQueue]];
self.postDataTask = [session dataTaskWithRequest:request];
[self.postDataTask resume];
[session finishTasksAndInvalidate];
}
如果你不这样做 finishTasksAndInvalidate
,你会看到像这样的泄漏:
调用 finishTasksAndInvalidate
将解决这些问题。
在 xcode 仪器中,我遇到此方法内存泄漏
- (void)getDataForRequest:(NSURLRequest *)request completionHandler:(downloadCompletionBlock)completionHandler
{
self.expectedLength = 0;
self.currentLength = 0;
self.responseData = Nil;
self.contentLengthBlock = nil;
self.completionBlock = completionHandler;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];
self.postDataTask = [session dataTaskWithRequest:request];
[self.postDataTask resume];
}
问题可能出在短语 delegate: self
上。 NSURLSession 保留其委托。因此,您告诉会话保留此实例(可能是视图控制器)。在您使会话无效之前,视图控制器不会消失。
解决方法是:正确管理会话。保留对会话的引用,以便稍后可以使它无效。更好的是,使委托成为轻量级对象,不同于视图控制器,您可以管理其内存。
此代码段中的一个问题是您正在为每个请求创建一个新的 NSURLSession
,并且您永远不会使会话无效。如果发起请求后调用finishTasksAndInvalidate
,则:
- 请求完成后,回收与
NSURLSession
关联的内存;通过这样做,它也将 - 释放对
delegate
对象的强引用。
因此:
- (void)getDataForRequest:(NSURLRequest *)request completionHandler:(DownloadCompletionBlock)completionHandler {
self.expectedLength = 0;
self.currentLength = 0;
self.responseData = nil;
self.contentLengthBlock = nil;
self.completionBlock = completionHandler;
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:[NSOperationQueue mainQueue]];
self.postDataTask = [session dataTaskWithRequest:request];
[self.postDataTask resume];
[session finishTasksAndInvalidate];
}
如果你不这样做 finishTasksAndInvalidate
,你会看到像这样的泄漏:
调用 finishTasksAndInvalidate
将解决这些问题。