Как предотвратить NSManagedObjectContext от повреждения базы данных, когда поток убит при сохранении? - PullRequest
1 голос
/ 02 июня 2011

В этом вопросе octy написал :

Кстати, если вы экономите на фоне нить, вам также нужно учитывать, что происходит, когда ваше приложение закрывается пока выполняется операция сохранения. Фоновые потоки убиты правильно прочь, тогда как сторож ждет 5 секунд до окончания основного потока до.

Теперь я потратил весь день на реализацию NSOperation и создание экземпляров NSManagedObjectContext непосредственно внутри подклассов NSOperation, так что у каждого NSOperation есть собственный нераспределенный MOC. Но сейчас это очень плохие новости, поскольку подобный сценарий, который, вероятно, происходит постоянно, повредит базу данных Core Data. Я имею в виду, что он не может начать писать полбайта чего-то в файле sqlite3, а затем просто сразу остановиться.

И еще одна проблема: в своих операциях NSO я также делаю файловый ввод-вывод с NSFileManager.

Так что я могу с этим поделать? Я должен следить за всеми запущенными NSOperations и NSOperationQueues в моем приложении и быстро позаботиться о них в App Delegate, когда приложение будет завершено, чтобы я мог сообщить NSOperations SFF (Save F ***** g Fast) или отменить все операции, захватить их MOC и немедленно «жестко сохранить» их? Как лучше всего решить эту проблему?

И почему я слышу об этом впервые в моей карьере? Я имею в виду, что ни в одной из книг, упоминающих NSOperationQueue и Core Data, даже не говорится об этом, но кажется, что это случайный убийца приложений, который вынуждает пользователя переустанавливать (и, возможно, терять тонны данных), если мы не позаботимся об этом.

1 Ответ

1 голос
/ 02 июня 2011

Основная сила MOC заключается в том, что он представляет собой абстрактное хранилище, которое не зависит от формата. Он хранит все свои объекты в памяти и использует механизм транзакций для фиксации любых изменений. Поэтому, когда вы вставляете / удаляете / редактируете некоторые объекты, которые в MOC изменяются только в памяти, а не в постоянном хранилище (будь то база данных SQLite, файл XML или что-то еще). Изменения вступают в силу только при вызове метода save:.

Что касается NSOperation и обработки файлов: если вы хотите остановить какую-либо операцию, вы должны позвонить cancel для этого. Из документов:

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

Это означает, что при выполнении какой-либо операции ввода-вывода при отмене операции операция будет ждать до ее завершения.

Также, несмотря на механизм транзакций Core Data, вы должны реализовать свой собственный для любых данных, которыми он не управляет (при необходимости).

...