2

У меня очень сложная проблема, которую я провел дни, чтобы понять и понять, что я не уверен, как ее исправить.Предотвращение события NSManagedObjectContextDidSaveNotification для перекрытия

У меня есть база данных CoreData, обновленная из разных потоков с различным контекстом. Моя проблема в том, что иногда событие NSManagedObjectContextDidSaveNotification перекрывается и создает повреждение базы, которая приводит к сбою. Вот пример:

Thread     Main           NSFetchResultsController 

Update database 
Save database   NSManagedObjectContextDidSaveNotification1 
         merge           delegate process 1 
                     process 1 done 

Update database 
Save database   NSManagedObjectContextDidSaveNotification2 
         merge           delegate process 2 
                     process 2 done 
Update database 
Save database   NSManagedObjectContextDidSaveNotification3 
         merge           delegate process 3 

Update database 
Save database   NSManagedObjectContextDidSaveNotification4 
         merge   

                     process 3 done 
                     delegate process 4 
                     CRASH 
                     process 4 done 

В этом псевдокоде пример Process1 и Process2 работает без проблем, но иногда основной поток получает перекрывающееся событие обновления и вы process4 начать читать базу данных перед процессом 3 делаются.

Есть ли официальный способ справиться с этим? Предлагает ли CoreData решение в этой ситуации или мне нужно использовать NSLock?

Благодаря

+0

Можете ли вы опубликовать часть своего кода, обрабатывающую уведомление о слиянии? Без этого я не думаю, что гораздо больше можно будет вывести. Как я уже сказал в своем ответе, контексты блокируют постоянный координатор хранилища для сериализации доступа, что должно предотвратить такие проблемы. – paulbailey

ответ

2

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

Если процесс 3 и процесс 4 выполняются на основном потоке, то как начать 4 до 3? Не забывайте, что уведомления отправляются в поток, который отправляет их, поэтому вам нужно явно выполнить свой код, чтобы объединить изменения в основном потоке (извинения, если я заявляю очевидное).

+0

Спасибо за ваш комментарий. Я обновил свой вопрос, поскольку, как выясняется, это еще более сложно, поскольку в нем задействован NSFetchResultsController. Так или иначе база данных иногда обновляется, когда NSFetchResultsControllerDelegate обрабатывает последнее обновление, и это вызывает проблемы – CodeFlakes

+1

Я думаю, что контроллер и его делегат - это красная селедка. Эта деятельность должна происходить в основном потоке. Такие сбои почти всегда возникают из-за того, что контекст используется из потока, отличного от того, который его создал. – paulbailey