У меня есть приложение Cocoa на основе документов, использующее CoreData, которое может импортировать большие объемы данных. Поскольку этот импорт занимает некоторое время, я делаю это в фоновом режиме, но поскольку NSManagedObjectContext
не является сохранением потока, я использовал persistentStoreCoordinator
из managedObjectContext
документа для создания нового NSManagedObjectContext
в фоновом потоке. Теперь, когда импорт завершен, я сохраняю фон managedObjectContext
, чтобы уведомить основной поток документа managedObjectContext
об изменениях и объединить их. Насколько я понимаю, именно так должен выполняться параллелизм с использованием CoreData.
Но иногда у persistentStoreCoordinator
нет persistentStore
, когда я вызываю [managedObjectContex save:]
, что приводит к сбою сохранения и сбою приложения. Я использую автосохранение и все такое (в основном немодифицированный NSPersistentDocument в OS X 10.8), поэтому я предположил, что мне не нужно заботиться о том, как он сохраняется, и он будет «просто работать».
Судя по всему, это не так. Я попытался форсировать операцию автосохранения, надеясь, что это создаст persistenceStore, вызвав [self autosaveDocumentWithDelegate:self didAutosaveSelector:@selector(document:didAutosave:contextInfo:) contextInfo:nil];
в конце windowControllerDidLoadNib:
в моем подклассе документа, но, похоже, это ничего не меняет. Обратный вызов делегата (- (void)document:(NSDocument *)document didAutosave:(BOOL)didAutosaveSuccessfully contextInfo:(void *)contextInfo
) фактически указывает, что автосохранение было успешным, хотя ни один из файловых URL-адресов или связанных методов доступа не возвращает что-то отличное от нуля, и не было создано persistingStore.
Я также подумал о том, чтобы самому вызвать -(BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError *__autoreleasing *)error
, но я не знаю, какой URL использовать, чтобы он работал как обычное автосохранение. Я проверил backupFileURL
, fileURL
и autosavedContentsFileURL
, но все они по-прежнему равны нулю в конце windowControllerDidLoadNib:
. На самом деле они равны нулю даже после того, как были вызваны writeToURL:...
и configurePersistentStoreCoordinatorForURL:...
, поэтому я понятия не имею, как получить "правильный" URL.
Чтобы лучше понять, как и когда создается постоянное хранилище, я установил контрольные точки в writeToURL:...
и configurePersistentStoreCoordinatorForURL:...
. Я заметил, что configurePersistentStoreCoordinatorForURL:
вызывается, когда приложение теряет самый передний статус. Но когда я просто создаю новый документ и пытаюсь импортировать что-то сразу после его создания (без предварительного переключения на другое приложение, чтобы вызвать создание постоянного хранилища), он падает. Если я переключаюсь на другое приложение, магазин создается и все работает нормально. Кстати, URL-адрес, используемый для созданного таким образом постоянного хранилища, всегда находится где-то во временном каталоге.
Я делаю что-то неправильно? Разве мне не нужно вызывать [managedObjectContext save:], чтобы уведомить другой ManagedObjectContext об изменениях? Как я могу заставить документ создать свое временное хранилище? Почему вызов autosaveDocumentWithDelegate:...
фактически не сохраняет документ (и, таким образом, не создает persistentStore
)?
Связанный:
- Новый проект Новая модель NSPersistentDocument Этот NSPersistentStoreCoordinator не имеет постоянных хранилищ Аналогично проблема, но решение заключалось в том, чтобы не сохранять контекст или не отображать ошибку. Я думаю, что мне нужно сохранить контекст, чтобы уведомить второго об изменениях, и не хочу заставлять пользователя сохранять файл вручную (в конце концов, для этого и предназначено автосохранение).