Я пытаюсь создать некоторые методы, которые облегчат выполнение базовых данных в фоновом режиме.То, что я делаю:
- Используйте
NSOperationQueue
-addOperationWithBlock:
для создания фонового потока - В фоновом потоке создайте
NSManagedObjectContext
с тем же persistentStoreCoordinator
в качестве контекста в главном потоке и с undoManager
, установленным на nil
Добавить наблюдателя в центр уведомлений по умолчанию для прослушивания NSManagedObjectContextDidSaveNotification
уведомлений и обрабатывать их так:
- (void)mergeChanges:(NSNotification *)notification
{
dispatch_sync(dispatch_get_main_queue(), ^{
[_mainContext mergeChangesFromContextDidSaveNotification:notification];
});
}
Выполнить блок, который был передан и который выполняет всю работу с основными данными.Периодически он вызывает save:
в фоновом контексте
- Как только все будет сделано, удалите наблюдателя из центра уведомлений
Описанный метод можно найти ниже.
Все работает как положено.Я могу передать блоки, которые добавляют данные, обновляют данные или удаляют данные. Но : я получаю следующую ошибку, когда закрываю приложение с некоторыми данными, заново открываю его и затем пытаюсь удалить данные в фоновом режиме:
CoreData: ошибка: серьезнаяОшибка приложения.Исключение было получено от делегата NSFetchedResultsController во время вызова -controllerDidChangeContent :.CoreData не может выполнить ошибку для [...]
Как видно из ошибки, я использую NSFetchedResultsController
для отображения данных.Кеш контроллера установлен на nil
.
Есть предложения как это исправить?
Вот соответствующий код.Обратите внимание, что я использую ARC.
FJCoreDataBackgroundBlock
определяется следующим образом:
typedef void(^FJCoreDataBackgroundBlock)(NSManagedObjectContext *backgroundContext);
Метод выполнения нескольких базовых данных в фоновом режиме
- (void)performBlockInBackground:(FJCoreDataBackgroundBlock)block
{
[FJSharedOperationQueue addOperationWithBlock:^{
self.managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setUndoManager:nil];
[_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
[self setupNotificationCenterObserverForContext:_managedObjectContext];
FJCoreDataBackgroundBlock backgroundBlock = [block copy];
backgroundBlock(self.managedObjectContext);
[self saveBackgroundContext];
[self saveMainContext];
[self removeNotificationCenterObserver];
}];
}
Реализация FJSharedOperationQueue
:
+ (NSOperationQueue *)sharedQueue
{
static dispatch_once_t predicate = 0;
__strong static NSOperationQueue *_sharedQueue = nil;
dispatch_once(&predicate, ^{
_sharedQueue = [[NSOperationQueue alloc] init];
[_sharedQueue setMaxConcurrentOperationCount:1];
});
return _sharedQueue;
}
+ (void)addOperationWithBlock:(void (^)(void))block
{
[[FJSharedOperationQueue sharedQueue] addOperationWithBlock:block];
}