0

I have to read a very large file into memory (data processing while reading it is not an option, I have to have the entire file in the device memory). When the device runs out of memory, I should stop the reading and display an error message to the user.

- (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];
}

In my stream delegate method I am checking the _didReceiveMemoryWarning variable every time, and close the stream if it becomes 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;
}

The reading works on the simulator because I have sufficient memory there, however on the device the OS seems to kill the app before I receive the notification (With smaller files it works on the device as well). Does anyone know a solution to this problem?

Levi
  • 7,313
  • 2
  • 32
  • 44
  • Can you check if your UIApplicationDelegate gets a memory warning by implementing [applicationDidReceiveMemoryWarning](http://developer.apple.com/library/ios/documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/applicationDidReceiveMemoryWarning:)? – Luc Wollants Aug 13 '13 at 11:06
  • I would argue that this is not a good concept to be required for a mobile app. Also what is the user expected to do when such a warning would show up? The system handles all memory, nothing the user can do. Depending the processing on an non guaranteed notification won't work either. The requirement having a large amount of data in memory just doesn't fit the mobile environment. – Kerni Aug 13 '13 at 11:08

1 Answers1

1

You could try monitoring memory usage in your application. This class addition shows the MB in use by the application, with NSlogs. Remember you are not necessarily looking for a high amount of memory in use, but also fluctuations in memory.

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

Jeevan Thandi
  • 158
  • 2
  • 11