2013-08-13 2 views
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 переменные каждый раз, и закрыть поток, если он становится истинным.

... 
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; 
} 

Показание работает на тренажере, потому что у меня есть достаточно памяти там, однако на устройстве ОС, кажется, убить приложение, прежде чем я получить уведомление (с небольшими файлами он работает на устройстве, а). Кто-нибудь знает решение этой проблемы?

+0

Вы можете проверить, если ваш UIApplicationDelegate получает предупреждение памяти путем внедрения [applicationDidReceiveMemoryWarning] (http://developer.apple.com/library/ios/documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference. HTML # // apple_ref/ОКК/intfm/UIApplicationDelegate/applicationDidReceiveMemoryWarning :)? –

+0

Я бы сказал, что это не очень хорошая концепция для мобильного приложения. И что пользователь должен ожидать, когда появится такое предупреждение? Система обрабатывает всю память, ничего не может сделать пользователь. В зависимости от обработки не гарантированного уведомления также не будет работать. Требование, имеющее большой объем данных в памяти, просто не соответствует мобильной среде. – Kerni

ответ

1

Вы можете попробовать контролировать использование памяти в своем приложении. Это добавление класса показывает MB, используемое приложением, с NSlogs. Помните, что вы не обязательно ищете большой объем используемой памяти, но также и колебания в памяти.

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