executeBlockAndWait: синхронное сохранение контекста корневого управляемого объекта не обеспечивает временные идентификаторы объектов - PullRequest
3 голосов
/ 28 октября 2011

Следуя примечаниям к выпуску iOS5 и примерам презентаций WWDC2011, я настроил контекст корневого управляемого объекта как тип NSPrivateQueueConcurrencyType .У меня есть дочерний контекст, который имеет тип NSMainQueueConcurrencyType (упоминаемый как контекст по умолчанию).

Когда я сохраняю дочерний контекст, затем сохраняйте корневой контекст, используя блочный API: performBlockAndWait: Я ожидаю, что операция будет синхронной.

То есть сразу после выполнения этого блока я смогу получить невременные ObjectID для всех объектов, только что вставленных в хранилище данных.

Однако вместо этого я получаю временные идентификаторы объектов!Это как если бы performBlockAndWait: вырождается в performBlock: и работает асинхронно.Но почему?

Это ошибка, или я пропускаю какое-то ключевое предположение?

Вот некоторый соответствующий код:

// Setup of the root MOC:
__rootContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__rootContext setPersistentStoreCoordinator:[self coordinator]];

// Setup of the child MOC; I use it as the "default" context:
__defaultContext = [[NSManagedObjectContext alloc] 
    initWithConcurrencyType:NSMainQueueConcurrencyType];
[__defaultContext setParentContext:__rootContext];

// Here's the essence of the save operation:
[__defaultContext save:&error]

// Setup a block I can invoke that does the save:
void (^rootContextSaveOperation)(void) = ^{
    NSError *rootContextError = nil;
    BOOL wasRootContextSaveSuccessful = [rootContext save:&rootContextError];
    if (!wasRootContextSaveSuccessful) { 
        NSLog(@"RPDataStore: Error saving root context."); }
    };

// Call perform block and wait with the operation:
[__rootContext performBlockAndWait:rootContextSaveOperation];

// Now when I inspect one of the objects just saved, I have this check in my unit test:
BOOL isTempID = [[user objectID] isTemporaryID];

Проблема в том, что "пользователь"«Объектная часть иерархии MOC, только что сохраненная из его конечного MOC в корень, флаг« isTempID », к сожалению, показывает« ДА ».

Я ожидал, что смогу выполнить синхронное сохранение, чтобы получить постоянный объектИдентификатор, который я мог бы использовать в других контекстах.

Являются ли мои концептуальные ожидания в отношении performBlockAndWait: неверными?

Если это так, как мне сохранить синхронно с этой конфигурацией очереди MOC и при этом получить невременные ObjectIDпрямо сейчас?

1 Ответ

2 голосов
/ 30 октября 2011

Для кого это могло бы быть полезным, мой обходной путь состоял в том, чтобы построить прогноз выборки для управляемого объекта, который будет однозначно извлекать его.

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

Другим вариантом является получение постоянных идентификаторов объектов для всех объектов в контексте до первоначального сохранения дочернего контекста. Затем вы можете использовать NSManagedObjectContext refreshObject:mergeChanges:, чтобы обновить текущую ссылку определенного объекта в области видимости. Теперь он будет отражать изменения, только что сохраненные в дочернем контексте.

Получение постоянных идентификаторов объектов с использованием метода NSManagedObjectContext obtainPermanentIDsForObjects:error:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...