非常に大きなファイルをメモリに読み込む必要があります (読み込み中のデータ処理はオプションではなく、ファイル全体をデバイス メモリに保存する必要があります)。デバイスのメモリが不足したら、読み取りを停止し、ユーザーにエラー メッセージを表示する必要があります。
- (void)setUpStreamForFile:(NSString *)path {
_inputStream = [[NSInputStream alloc] initWithFileAtPath:path];
[_inputStream setDelegate:self];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
_didReceiveMemoryWarning = YES;
}];
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_inputStream open];
}
私のストリーム デリゲート メソッドでは、_didReceiveMemoryWarning
毎回変数をチェックしており、true になったらストリームを閉じます。
...
if (!_didReceiveMemoryWarning) {
if(!_tempData) {
_tempData = [NSMutableData data];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[_tempData appendBytes:(const void *)buf length:len];
}
} else {
[self closeInputStream];
NSError *error error = [NSError errorWithDomain...];
[[NSNotificationCenter defaultCenter] postNotificationName:@"reading failed" object:error];
_didReceiveMemoryWarning = NO;
}
...
- (void)closeInputStream {
[_inputStream close];
[_inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
_inputStream = nil;
_tempData = nil;
}
十分なメモリがあるため、シミュレーターで読み取りが機能しますが、デバイスでは、通知を受け取る前に OS がアプリを強制終了しているように見えます (小さいファイルの場合、デバイスでも機能します)。誰もこの問題の解決策を知っていますか?