iPhone - файл 3 Мб в NSArray == 22 Мб - PullRequest
0 голосов
/ 26 мая 2011

Мое приложение закрывается на 3G iPhone ~ 23 Мб ..

Я загружаю файл 3mb в NSArray следующим образом ... str и строки не освобождаются автоматически? Любые предложения о лучшем способе сделать это?

NSString *str = [NSString stringWithContentsOfFile:path 
              encoding:NSUTF8StringEncoding error:&error];
NSArray *lines = [str componentsSeparatedByString: @"\n"];
[self parseDictLines:lines];


- (void)parseDictLines:(NSArray *)lines {
    int i = 0; 
    NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
    NSMutableArray *word_list = [[NSMutableArray alloc] init];
    for (NSString *line in lines) {
        i++;
        [arr addObject:line];

        if ( i == 3 ) {
            i = 0;
            [word_list addObject:[arr copy]];
            [arr removeAllObjects];
        }
    }
    self.mDict = (NSArray*)word_list;
    [word_list release];
} 

РЕДАКТИРОВАТЬ - приложение <1 МБ до этого кода или если я пропущу этот код. Это 22 МБ после запуска ... Так что это не может быть временная переменная ... Его можно использовать, пока я не сделаю что-то, что добавляет еще 1 МБ, и в этот момент он освобождается от обязательств. </p>

EDIT2 - NSString * str файла составляет 5,9 МБ - я полагаю, из-за того, как строка кодируется в памяти, в два раза больше, чем файл UTF8. Массив * lines также имеет такой размер.

Однако str не выпускался сразу, пока я не добавил пул автоматического выпуска. При работе с инструментами заполнение строк NSArray * занимает 5 минут, после вызова [освобождение строк] прошло около 3 минут, прежде чем память начала уходить, и 5 минут после этого, прежде чем память, используемая массивом * lines, была отключена. до <1 Мб. Мой массив mDict составляет 14 МБ. Я не знаю, почему, поскольку он не так сильно отличается от строк NSArray *, который был 6 МБ ... </p>

Приведенный ниже код решает мою проблему, которая, очевидно, заключалась в том, что я достиг предела памяти до освобождения памяти str и lines. Теперь, когда str выпущен сразу же, он освобождает 6 МБ, и пользователь не может превысить ограничение сейчас, пока этот код загружается в фоновом режиме.

НО - Почему ОС сбрасывает мое приложение, когда я уже автоматически выпустил 12 Мб? Разве это не очистило бы что-нибудь, что должно быть автоматически выпущено самостоятельно?

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
NSArray *lines = [[str componentsSeparatedByString: @"\n"] retain];
[pool drain];
[self parseDictLines:lines];
[lines release];

Ответы [ 3 ]

3 голосов
/ 26 мая 2011

вы слишком долго сохраняете переменную arr.Вам следует заменить

[word_list addObject:[arr copy]];

на

[word_list addObject:arr];
0 голосов
/ 26 мая 2011

Запустите его через инструмент Распределения инструментов, и вы сможете увидеть, куда идет память.

0 голосов
/ 26 мая 2011

Один из подходов заключается в настройке пула NSAutoRelease перед циклом, который вы сливаете сразу после [arr removeAllObjects].Осушение пула - это то же самое, что и его освобождение, поэтому после этого вам необходимо снова выделить / инициализировать пул.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...