Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit b617a8c

Browse files
committed
Fix IOS memory leaks
1 parent 889c038 commit b617a8c

File tree

5 files changed

+38
-26
lines changed

5 files changed

+38
-26
lines changed

src/ios/RNFetchBlob/RNFetchBlob.m

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ - (NSDictionary *)constantsToExport
6363
callback:(RCTResponseSenderBlock)callback)
6464
{
6565

66-
[RNFetchBlobReqBuilder buildMultipartRequest:options taskId:taskId method:method url:url headers:headers form:form onComplete:^(NSURLRequest *req, long bodyLength) {
66+
[RNFetchBlobReqBuilder buildMultipartRequest:options taskId:taskId method:method url:url headers:headers form:form onComplete:^(__weak NSURLRequest *req, long bodyLength) {
6767
// send HTTP request
6868
RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
6969
[utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
70-
utils = nil;
7170
}];
7271

7372
}
@@ -80,13 +79,10 @@ - (NSDictionary *)constantsToExport
8079
headers:(NSDictionary *)headers
8180
body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
8281
{
83-
NSString *cType = [headers valueForKey:@"content-type"];
84-
8582
[RNFetchBlobReqBuilder buildOctetRequest:options taskId:taskId method:method url:url headers:headers body:body onComplete:^(NSURLRequest *req, long bodyLength) {
8683
// send HTTP request
87-
RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
84+
__block RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
8885
[utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
89-
utils = nil;
9086
}];
9187
}
9288

src/ios/RNFetchBlobFS.m

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ + (void) readFile:(NSString *)path encoding:(NSString *)encoding
304304
@try
305305
{
306306
[[self class] getPathFromUri:path completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
307-
NSData * fileContent;
307+
__block NSData * fileContent;
308308
NSError * err;
309-
Byte * buffer;
309+
__block Byte * buffer;
310310
if(asset != nil)
311311
{
312312
buffer = malloc(asset.size);
@@ -672,10 +672,11 @@ + (void) getPathFromUri:(NSString *)uri completionHandler:(void(^)(NSString * pa
672672
if([uri hasPrefix:AL_PREFIX])
673673
{
674674
NSURL *asseturl = [NSURL URLWithString:uri];
675-
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
675+
__block ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
676676
[assetslibrary assetForURL:asseturl
677677
resultBlock:^(ALAsset *asset) {
678-
onComplete(nil, [asset defaultRepresentation]);
678+
__block ALAssetRepresentation * present = [asset defaultRepresentation];
679+
onComplete(nil, present);
679680
}
680681
failureBlock:^(NSError *error) {
681682
onComplete(nil, nil);

src/ios/RNFetchBlobNetwork.m

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ - (NSString *)md5:(NSString *)input {
109109
}
110110

111111
// send HTTP request
112-
- (void) sendRequest:(NSDictionary * _Nullable )options
112+
- (void) sendRequest:(__weak NSDictionary * _Nullable )options
113113
contentLength:(long) contentLength
114114
bridge:(RCTBridge * _Nullable)bridgeRef
115115
taskId:(NSString * _Nullable)taskId
116-
withRequest:(NSURLRequest * _Nullable)req
116+
withRequest:(__weak NSURLRequest * _Nullable)req
117117
callback:(_Nullable RCTResponseSenderBlock) callback
118118
{
119119
self.taskId = taskId;
@@ -127,19 +127,19 @@ - (void) sendRequest:(NSDictionary * _Nullable )options
127127
NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
128128
NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
129129
NSString * key = [self.options valueForKey:CONFIG_KEY];
130-
NSURLSession * session;
130+
__block NSURLSession * session;
131131

132132
bodyLength = contentLength;
133133

134134
// the session trust any SSL certification
135135

136+
136137
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
137138
if([options valueForKey:@"timeout"] != nil)
138139
{
139140
defaultConfigObject.timeoutIntervalForRequest = [[options valueForKey:@"timeout"] floatValue];
140141
}
141142
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:taskQueue];
142-
143143
if(path != nil || [self.options valueForKey:CONFIG_USE_TEMP]!= nil)
144144
{
145145
respFile = YES;
@@ -229,10 +229,13 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
229229
@"timeout" : @NO,
230230
@"status": [NSString stringWithFormat:@"%d", statusCode ]
231231
};
232+
232233
[self.bridge.eventDispatcher
233234
sendDeviceEventWithName: EVENT_STATE_CHANGE
234235
body:respInfo
235-
];
236+
];
237+
headers = nil;
238+
respInfo = nil;
236239
}
237240

238241
if(respFile == YES)
@@ -259,7 +262,8 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
259262
// download progress handler
260263
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
261264
{
262-
receivedBytes += [data length];
265+
NSNumber * received = [NSNumber numberWithLong:[data length]];
266+
receivedBytes += [received longValue];
263267
if(respFile == NO)
264268
{
265269
[respData appendData:data];
@@ -280,10 +284,18 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
280284
}
281285
];
282286
}
287+
received = nil;
283288

284289
}
285290

286-
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
291+
- (void) URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error
292+
{
293+
if([session isEqual:session])
294+
session = nil;
295+
}
296+
297+
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
298+
{
287299

288300
self.error = error;
289301
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
@@ -313,6 +325,9 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
313325
[taskTable removeObjectForKey:taskId];
314326
[uploadProgressTable removeObjectForKey:taskId];
315327
[progressTable removeObjectForKey:taskId];
328+
respData = nil;
329+
receivedBytes = 0;
330+
[session finishTasksAndInvalidate];
316331
}
317332

318333
// upload progress handler

src/ios/RNFetchBlobReqBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
url:(NSString *)url
3636
headers:(NSDictionary *)headers
3737
form:(NSString *)body
38-
onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete;
38+
onComplete:(void(^)(__weak NSURLRequest * req, long bodyLength))onComplete;
3939

4040
+(NSString *) getHeaderIgnoreCases:(NSString *)field fromHeaders:(NSMutableArray *) headers;
4141

src/ios/RNFetchBlobReqBuilder.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ +(void) buildMultipartRequest:(NSDictionary *)options
3434
NSString * encodedUrl = url;
3535

3636
// send request
37-
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString: encodedUrl]];
37+
__block NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString: encodedUrl]];
3838
NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
3939
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
4040
NSNumber * timeStampObj = [NSNumber numberWithDouble: timeStamp];
4141

4242
// generate boundary
4343
NSString * boundary = [NSString stringWithFormat:@"RNFetchBlob%d", timeStampObj];
4444
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
45-
NSMutableData * postData = [[NSMutableData alloc] init];
45+
__block NSMutableData * postData = [[NSMutableData alloc] init];
4646
// combine multipart/form-data body
4747
[[self class] buildFormBody:form boundary:boundary onComplete:^(NSData *formData) {
4848
if(formData != nil) {
@@ -71,15 +71,15 @@ +(void) buildOctetRequest:(NSDictionary *)options
7171
url:(NSString *)url
7272
headers:(NSDictionary *)headers
7373
body:(NSString *)body
74-
onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete
74+
onComplete:(void(^)(__weak NSURLRequest * req, long bodyLength))onComplete
7575
{
7676
// NSString * encodedUrl = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
7777
NSString * encodedUrl = url;
7878
// send request
79-
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
79+
__block NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
8080
initWithURL:[NSURL URLWithString: encodedUrl]];
8181

82-
NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
82+
__block NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[RNFetchBlobNetwork normalizeHeaders:headers]];
8383
// move heavy task to another thread
8484
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
8585
NSMutableData * blobData;
@@ -88,7 +88,7 @@ +(void) buildOctetRequest:(NSDictionary *)options
8888
if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
8989
// generate octet-stream body
9090
if(body != nil) {
91-
NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
91+
__block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
9292
// when headers does not contain a key named "content-type" (case ignored), use default content type
9393
if(cType == nil)
9494
{
@@ -97,7 +97,7 @@ +(void) buildOctetRequest:(NSDictionary *)options
9797

9898
// when body is a string contains file path prefix, try load file from the path
9999
if([body hasPrefix:FILE_PREFIX]) {
100-
NSString * orgPath = [body substringFromIndex:[FILE_PREFIX length]];
100+
__block NSString * orgPath = [body substringFromIndex:[FILE_PREFIX length]];
101101
orgPath = [RNFetchBlobFS getPathOfAsset:orgPath];
102102
if([orgPath hasPrefix:AL_PREFIX])
103103
{
@@ -115,7 +115,7 @@ +(void) buildOctetRequest:(NSDictionary *)options
115115
// otherwise convert it as BASE64 data string
116116
else {
117117

118-
NSString * cType = [[self class]getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
118+
__block NSString * cType = [[self class]getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
119119
// when content-type is application/octet* decode body string using BASE64 decoder
120120
if([[cType lowercaseString] hasPrefix:@"application/octet"] || [[cType lowercaseString] containsString:@";base64"])
121121
{

0 commit comments

Comments
 (0)