2012-05-03 3 views
4

Я использую Core Data в своем приложении и обнаружил нечетное поведение симулятора: когда я добавляю некоторые данные в Core Data в свое приложение и выхожу из симулятора, используя кнопку «Stop» в XCode (или просто нажмите Cmd-Q) сразу же данные не сохраняются в базе данных при следующем запуске симулятора. После некоторого тестирования я узнал, что данные хранятся на диске:Когда Core Data сбрасывается на диск?

  • немедленно, если я нажму кнопку дома. (Почти - это : можно закрыть приложение до того, как данные будут сохранены, если выходите очень быстро.)
  • Если я запустил приложение на некоторое время (не менее 20 секунд) после добавления данных.

Это не поможет вызвать [NSManagedObjectContext save:]. Поведение такое же.

Так что мой вопрос: в чем причина такого поведения? Есть ли способ принудительно промыть диск перед выходом? И есть ли риск, что я могу потерять данные таким образом при работе на устройстве (лично я не вижу ничего, кроме силы закрытия, но странное поведение меня немного беспокоит)

ответ

7

Возможно, вы используете вложенный контекст. Если ваш контекст имеет родительский контекст, вызов -save: будет сохранен только в этом контексте, а не в файловой системе.

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

+0

Это правильно. Вызов '[context save: & error]; [[context parentContext] save: & error]; 'выполняет задание, и данные немедленно сохраняются на диске. Я должен сделать оба вызова (что разумно), но, на удивление, не имеет значения, если я сначала вызову save в контексте или parentContext! У вас есть объяснение? – JRV

+1

BTW, как примечание для других: я сам не создал вложенные контексты, так что это происходит «за кулисами». – JRV

+3

Вы должны * не * называть '[[context parentContext] save: & error]' на thead контекста, который не является потокобезопасным (как я указал). Вам нужно вызвать '[[context parentContext] executeBlock: ^() {[[context parentContext] save: NULL]}];' (или тому подобное) –

10

Остановка симулятор с кнопка остановки в Xcode, вероятно, такая же, как разбивка вашего iPhone молотком (но сохранение SSD). В основном, ваше приложение и все остальное просто останавливается. Нет разумного способа гарантировать, что данные будут сохранены, когда это произойдет.

+1

+1 заставило меня улыбнуться – bearMountain

0

Я тоже долго боролся с этим, и ответ Даниэля Эггерт в соответствии с (2) выше - это первый и единственный полезный ответ, который я нашел в Интернете. Я предполагаю, что JRV использует NSManagedDocumentContext из UIManagedDocument. Если это так, то метод сохранения «по умолчанию» Apple является неполным! Приняв решение Даниэля Эггерт, мои данные теперь отлично сохраняются и также невосприимчивы к жесту симулятора «СТОП». Я рекомендую Даниэлю Эггерту ответ в соответствии с (2) выше всем, кто хочет написать в этом случае устойчивый код.