Ошибка импорта основных данных - PullRequest
1 голос
/ 08 февраля 2011

Я пытаюсь импортировать большой набор данных (~ 6000) в мое основное приложение данных.Я прочитал документ Apple «Эффективный импорт данных» и думаю, что настроил его правильно.Странно то, что приложение не падает в симуляторе, хотя оно происходит, если я запускаю его с инструментом Leaks, но не сохраняет все данные.Иногда это спасет только 3-4 сотни, а иногда сэкономит 3-4 тысячи, а реже весь набор данных.Я думаю, что это, вероятно, связано с утечкой памяти, и я довольно плохо знаком с NSAutoReleasePool, любая помощь будет высоко ценится.

Ответы [ 2 ]

0 голосов
/ 10 февраля 2011

Я не вижу ничего хитрого в коде. Определенно нет ошибок в журнале?

Кстати, еще один совет по оптимизации, описанный в PDF-файле Core Data для импорта данных, заключается в том, чтобы переместить создание предиката за пределы цикла и использовать переменные подстановки.

0 голосов
/ 08 февраля 2011

Я не вижу никаких явных утечек, но:

  1. Вы можете минимизировать объем памяти, используемый alloc init retain -ing NSLocale, NSDateFormatter, NSNumberFormatter, а затем release -ing их после завершения цикла. Кажется, что они не меняются между циклами цикла.

  2. Я не знаю Базовые Данные, но где освобождается объект NSManagedObject / Player *player? Выпускается ли это автоматически через Core Data?

  3. В качестве отступления вы можете использовать [list lastObject] вместо [list count] и [list objectAtIndex:0], так как последние два будут аварийно завершать работу, если список равен nil

Обновление на основе ответа:

Если кажется, что ничего не изменится, следующим шагом будет упрощение кода с целью устранения любых источников ошибок.

  1. Выполните мои предложения в # 1 выше, чтобы минимизировать количество кода в цикле.

  2. Убедитесь, что вы освобождаете объект list где-то или что он выделен как авто-релиз.

  3. Удалите промежуточное сохранение (весь этот код внутри count == LOOP_LIMIT) и сохраняйте и сливайте пул только после обработки всех массивов. Вам также не понадобится следующий код внутри if (count != 0)

  4. Замените операторы error:nil на правильные error:&&error и зарегистрируйте ошибки. Для регистрации ошибок сделайте следующее (извинения, но форматирование кода не работает - не знаю почему): NSError *error = nil; //Declared upfront

    // Your streamlined code

    // ....

    error = nil; //Just before a fetchRequest or context:save

    /* After looping through all your code now attempt to save */

    if(![context save:&error]) {

    NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
    NSArray *detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
    if(detailedErrors != nil && [detailedErrors count] > 0) {
        for(NSError *detailedError in detailedErrors) {
            NSLog(@"DetailedError: %@", [detailedError userInfo]);
        }
    } else {
        NSLog(@" %@", [error userInfo]);
    }
    

    }

  5. Затем проверьте журнал, чтобы увидеть, если вы получаете какие-то странные сообщения. Вы также можете использовать аналогичный код в любом месте Базовых данных, которые вам нужно проверить на наличие ошибок (т.е. executeFetchRequest). Стоит попытаться выяснить, в чем здесь ошибка.

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