Основные данные и NSOperation

В настоящее время я работаю с подклассом NSPersistentDocument , который использует NSOperation для импорта данных в фоновом режиме. Согласно документации, я наблюдаю за NSManagedObjectContextDidSaveNotification после сохранения в фоновой задаче и распространения уведомления в NSManagedObjectContext в основном потоке с помощью -mergeChangesFromContextDidSave2793]: .

Все работает нормально, но представляет собой странный рабочий процесс для пользователя, который импортирует данные в новый документ. Им необходимо сохранить пустой документ перед выполнением импорта (в противном случае -save: не работает, потому что в документе не настроен URL-адрес для NSPersistentStoreCoordinator .) Я не вижу другого выхода, кроме какого-то мастера «установки нового документа», который гарантирует - writeToURL: ofType: forSaveOperation: originalContentsURL: error: вызывается перед импортом.

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

Я прочтите как Руководство по программированию основных данных , так и книгу Маркуса Зарры, но я все еще новичок в этом аспекте структуры. Надеюсь, я кое-что упустил: в противном случае я приспособлю свое приложение к этим ограничениям (преимущества Core Data намного перевешивают эти ограничения пользовательского интерфейса).

Спасибо за ваше время!

-

Основываясь на предложении Питера Хози ниже, я добавил следующий код для создания временного постоянного хранилища перед импортом:

NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
if ([[persistentStoreCoordinator persistentStores] count] == 0) {
    // create an in-memory store to use temporarily
    NSError *error;
    NSPersistentStore *persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error];
    if (! persistentStore) {
        NSLog(@"error = %@", error); // TODO: better error handling
    }
}

Затем, после того, как файл выбран на панели сохранения, временное постоянное хранилище переносится в хранилище SQLite в выбранный URL:

- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
{
    NSPersistentStoreCoordinator *persistentStoreCoordinator = [self.managedObjectContext persistentStoreCoordinator];
    for (NSPersistentStore *persistentStore in [persistentStoreCoordinator persistentStores]) {
        if (persistentStore.type == NSInMemoryStoreType) {
            // migrate the in-memory store to a SQLite store
            NSError *error;
            NSPersistentStore *newPersistentStore = [persistentStoreCoordinator migratePersistentStore:persistentStore toURL:absoluteURL options:nil withType:NSSQLiteStoreType error:&error];
            if (! newPersistentStore) {
                NSLog(@"error = %@", error); // TODO: better error handling
            }
        }
    }

    return [super writeToURL:absoluteURL ofType:typeName forSaveOperation:saveOperation originalContentsURL:absoluteOriginalContentsURL error:error];
}
5
задан chockenberry 7 February 2011 в 22:32
поделиться