NSURLSession による連続ダウンロードにおけるメモリリーク (iOS8)
NSURLSession
を利用して 60個のファイル(それぞれ 2M程度)を連続ダウンロードしたいと思います。
以下のようなサンプルコードを作成し、うまくダウンロードできました。
ボタンを押すと 60個のファイルをダウンロードします。ダウンロードが終了すると再びボタンが有効になり、押下すると再度ダウンロードが始まります。
しかしながら、メモリ関連の問題が発生しました。
iOS7 では繰り返しダウンロードしても占有メモリは 50M程度で一定なのですが、
iOS8 ではダウンロード中に徐々に占有メモリが増加し、 1回実行すると 170MB程度となります。さらに繰り返し実行(Startボタンの押下)するとさらに占有量が増し、やがて Memory Warning が発生し、ついにはクラッシュしてしまいます。
どなたか解決の糸口をご教授していただける方、何卒宜しくお願いします。
#import "ViewController.h"
#define URL_MODEL_STRING @"http://sample.com/sample_%03d.pdf"
#define MAX_FILE_NUMBER 60
@interface ViewController ()<NSURLSessionDownloadDelegate>{
NSURLSessionConfiguration* _conf;
NSURLSession* _session;
NSURLSessionDownloadTask* _downloadTask;
int _currentFileNumber;
__weak IBOutlet UIButton *_startButton;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_conf = [NSURLSessionConfiguration defaultSessionConfiguration];
}
- (IBAction)startButtonPushed:(id)sender {
_startButton.enabled = NO;
_session = [NSURLSession sessionWithConfiguration:_conf
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
_currentFileNumber = 1;
[self downloadFileWithNumber:_currentFileNumber];
}
- (void)downloadFileWithNumber:(int)fileNumber{
NSURL* url = [self urlWithFileNumber:fileNumber];
_downloadTask = [_session downloadTaskWithURL:url];
[_downloadTask resume];
}
- (NSURL*)urlWithFileNumber:(int)fileNumber{
return [NSURL URLWithString:[NSString stringWithFormat:URL_MODEL_STRING, fileNumber]];
}
#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"fileNumber:%d location:%@", _currentFileNumber, location);
//TODO: Move downloaded temporary file to another place.
if(_currentFileNumber == MAX_FILE_NUMBER){
NSLog(@"Download complete.");
[_session invalidateAndCancel];
_startButton.enabled = YES;
return;
}
_currentFileNumber++;
[self downloadFileWithNumber:_currentFileNumber];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
NSLog(@"didReceiveMemoryWarning");
}
@end