0

非常に大きなファイルをメモリに読み込む必要があります (読み込み中のデータ処理はオプションではなく、ファイル全体をデバイス メモリに保存する必要があります)。デバイスのメモリが不足したら、読み取りを停止し、ユーザーにエラー メッセージを表示する必要があります。

- (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 がアプリを強制終了しているように見えます (小さいファイルの場合、デバイスでも機能します)。誰もこの問題の解決策を知っていますか?

4

1 に答える 1

1

アプリケーションのメモリ使用量を監視してみてください。このクラスの追加により、アプリケーションで使用中の MB が NSlogs で表示されます。必ずしも大量のメモリ使用量を探しているわけではありませんが、メモリの変動も調べていることに注意してください。

http://forrst.com/posts/Get_current_Memory_usage-hzw

于 2013-08-13T19:29:40.513 に答える