From 47f834a76d76d11bd6f5c2e5856098e5cbc83f83 Mon Sep 17 00:00:00 2001 From: "wenzhao.yin" Date: Thu, 20 Apr 2017 03:33:04 -0700 Subject: [PATCH] fix RCTMultipartDataTask Memory leaks Summary: In the Docs of `NSURLSession` , >IMPORTANT >The session object keeps a strong reference to the delegate until your app exits or explicitly >invalidates the session. If you do not invalidate the session, your app leaks memory until it exits. The RCTMultipartDataTask will cause memory leaks, it will make `RCTBatchedBridge` and ` RCTMultipartDataTask` will not release. So call `[session finishTasksAndInvalidate];` at the end of `startTask` function. Closes https://github.com/facebook/react-native/pull/12673 Reviewed By: shergin Differential Revision: D4896497 Pulled By: javache fbshipit-source-id: eb5f8761f67ad33a7de081a68a9a7e1d4329bfc0 --- React/Base/RCTMultipartDataTask.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/React/Base/RCTMultipartDataTask.m b/React/Base/RCTMultipartDataTask.m index 0fb1623db..27feaffbb 100644 --- a/React/Base/RCTMultipartDataTask.m +++ b/React/Base/RCTMultipartDataTask.m @@ -55,6 +55,7 @@ static BOOL isStreamTaskSupported() { } NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request]; [dataTask resume]; + [session finishTasksAndInvalidate]; } - (void)URLSession:(__unused NSURLSession *)session @@ -91,7 +92,9 @@ didReceiveResponse:(NSURLResponse *)response - (void)URLSession:(__unused NSURLSession *)session task:(__unused NSURLSessionTask *)task didCompleteWithError:(NSError *)error { - _partHandler(_statusCode, _headers, _data, error, YES); + if (_partHandler) { + _partHandler(_statusCode, _headers, _data, error, YES); + } } - (void)URLSession:(__unused NSURLSession *)session dataTask:(__unused NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data @@ -111,6 +114,7 @@ didBecomeInputStream:(NSInputStream *)inputStream { RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream boundary:_boundary]; RCTMultipartDataTaskCallback partHandler = _partHandler; + _partHandler = nil; NSInteger statusCode = _statusCode; BOOL completed = [reader readAllParts:^(NSDictionary *headers, NSData *content, BOOL done) {