Burak
Burak

Reputation: 5764

Receiving memory warning when downloading multiple files with AFNetworking

I am downloading movie files from UIGridViewCells. My code is:

NSMutableURLRequest* rq = [[APIClient sharedClient] requestWithMethod:@"GET" path:[[self item] downloadUrl] parameters:nil];
    [rq setTimeoutInterval:5000];
    _downloadOperation = [[AFHTTPRequestOperation alloc] initWithRequest:rq] ;
    _downloadOperation.outputStream = [NSOutputStream outputStreamToFileAtPath:[[self item] localUrl] append:NO];
    __weak typeof(self) weakSelf = self;
    [_downloadOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Successfully downloaded file to %@", [weakSelf.item localUrl]);
        [Helper saveItemDownloaded:weakSelf.item.productId];
        weakSelf.isDownloading = NO;
        [weakSelf.progressOverlayView removeFromSuperview];
        [weakSelf setUserInteractionEnabled:YES];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
        [weakSelf.progressOverlayView removeFromSuperview];
        [weakSelf setUserInteractionEnabled:YES];
        weakSelf.isDownloading = NO;
        }];
    [_downloadOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        float progress = totalBytesRead / (float)totalBytesExpectedToRead;
        weakSelf.progressOverlayView.progress = progress;
    }];
    [[NSOperationQueue mainQueue] addOperation:_downloadOperation];

And the property in ItemCell is:

@property (nonatomic, retain) AFHTTPRequestOperation *downloadOperation;

After 1-2 successful downloads(20mb), I am receiving Memory Warning. Memory using is increasing with each download, and never decrease when the download finishes.

enter image description here

From Instruments: enter image description here

Upvotes: 1

Views: 818

Answers (2)

Adri
Adri

Reputation: 530

I believe the preferred method of downloading files with AFNetworking is by setting the "outputStream" property.

According to AFNetworking documentation:

The output stream that is used to write data received until the request is finished.

By default, data is accumulated into a buffer that is stored into responseData upon completion of the request. When outputStream is set, the data will not be accumulated into an internal buffer, and as a result, the responseData property of the completed request will be nil. The output stream will be scheduled in the network thread runloop upon being set.

I was having the same problem, solved it by using "outputStream".

Upvotes: 2

Grzegorz Krukowski
Grzegorz Krukowski

Reputation: 19802

Use @autorelease per file downloaded:

for(File* file in fileList)
{
    @autoreleasepool {
        [self downloadFile:file];
    } 
}

This will release all variables and data allocated between separate files you download.

Also you should track down those memory leaks. I see some visible in instruments screenshots.

Upvotes: 0

Related Questions