Стратегия сохранения лучших основных данных (когда сохранять данные на диск)

Основываясь на вашем опыте, для приложения iOS, в котором используется только один NMPanagedObjectContext основного потока, лучший способ сохранить пользовательские настройки и кэшированные данные с сервера на диск в отношении надежности и производительности?

Я вижу следующие варианты:

  • сохранить контекст в конце каждого изменения.
  • сохранить контекст только при выходе приложения (например, в образцах Apple)
  • сохранить контекст при выходе из приложения, перейти на задний план или стать неактивным (например, входящий телефонный звонок)
  • добавить таймер, чтобы время от времени сохранять контекст, если он имеет какие-либо изменения.
  • вызовите специально подготовленную задержанную процедуру сохранения, которая соберет вместе вызовы для сохранения контекста, чтобы убедиться, что они не запускаются слишком часто.

В настоящее время мы используем 1-й вариант, поэтому могу сказать, что надежность этого очень хорошая, данные сохраняются даже после завершения Xcode приложения во время сеанса отладки, но производительность может пострадать, когда приложение становится все более сложным, esp, когда изменения в БД могут произойти в любой момент потока приложений из-за асинхронной загрузки данных с сервера.

С другой стороны, сохранение при определенных событиях приложения (выход, переход на фон и т.д.) даст лучшую производительность, но можете ли вы сказать по своему опыту, что достаточно убедиться, что пользователь не потеряет данные?

Ответ 1

Я думаю, что вам следует экономить часто, потому что он более надежный (вы не потеряете данные, если приложение выйдет из строя), и вы можете сэкономить освобожденную память, занятую модифицированными, но неиспользуемыми объектами.
В тот же момент вы не хотите подавлять db вашими запросами на сохранение.
Мое предложение состоит в том, чтобы разоблачить два метода в файле интерфейса и выбрать, какой из них вы хотите вызывать, в зависимости от ситуации.

- (void)save {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(save) object:nil];
    [_storage save:nil];
}

- (void)setNeedsSave {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(save) object:nil];
    [self performSelector:@selector(save) withObject:nil afterDelay:1.0];
}

Кроме того, рассмотрели ли вы использование второго контекста управляемого объекта с частной очередью? Вы можете настроить его как родительский контекст и сохранить/извлечь данные в фоновом режиме: http://www.cocoanetics.com/2012/07/multi-context-coredata/

Ответ 2

Сохранение контекста в методах UIApplicationDelegate applicationDidEnterBackground: и applicationWillTerminate: всегда было для меня прекрасным. Я также сохраняю в особых обстоятельствах, таких как большой импорт данных или что-то подобное.

Ответ 3

Я использовал для сохранения контекста при каждом изменении, но производительность действительно не так хороша. В настоящее время я сохраняю контекст в конце функции сбора данных. Производительность в 4 раза лучше. Просто убедитесь, что у вас есть [context lock] и [context unlock] в начале и в конце функции, если вы планируете вызывать функцию async в фоновом потоке.

Ответ 4

Согласно документации Apple "Рекомендуется сохранять пользовательские данные в соответствующих точках на протяжении всего выполнения приложения, обычно в ответ на определенные действия. Например, сохранять данные, когда пользователь закрывает экран ввода данных. Не полагайтесь на конкретное приложение". переходы между состояниями для сохранения критических данных всех ваших приложений ".