После небольшого эксперимента я решил немного изменить предложенный мной метод № 2. Выполняя фоновые изменения в контексте, сохраняйте счет объектов, которые вы хотите делегировать, в основном потоке, скажем, вNSMutableArray *objectsOfInterest
.В конечном итоге мы хотим получить ключи objectID
всех объектов в этом массиве, но поскольку значение objectID
изменяется при сохранении контекста, нам сначала нужно выполнить это [context save:&error]
.Сразу после сохранения используйте метод arrayFromObjectsAtKey:
из категории NSArray ниже, чтобы сгенерировать список objectID
экземпляров, например, так:
NSArray *objectIDs = [objectsOfInterest arrayFromObjectsAtKey:@"objectID"];
Этот массив вы можете безопасно вернуть обратно в основной поток черезделегат (убедитесь, что ваш контекст основного потока обновлен до mergeChangesFromContextDidSaveNotification
, слушая NSManagedObjectContextDidSaveNotification
).Когда вы будете готовы наложить объекты фоновой операции, используйте метод existingObjectsWithIDs:error:
из категории, приведенной ниже, чтобы превратить массив идентификаторов объектов в список рабочих NSManagedObject
s.
Любые предложениядля улучшения краткости или производительности этих методов приветствуется.
@implementation NSArray (Concurrency)
- (NSArray *)arrayFromObjectsAtKey:(NSString *)key {
NSMutableArray *objectsAtKey = [NSMutableArray array];
for (id value in self) {
[objectsAtKey addObject:[value valueForKey:key]];
}
return objectsAtKey;
}
@end
@implementation NSManagedObjectContext (Concurrency)
- (NSArray *)existingObjectsWithIDs:(NSArray *)objectIDs error:(NSError **)error {
NSMutableArray *entities = [NSMutableArray array];
@try {
for (NSManagedObjectID *objectID in objectIDs) {
// existingObjectWithID might return nil if it can't find the objectID, but if you're not prepared for this,
// don't use this method but write your own.
[entities addObject:[self existingObjectWithID:objectID error:error]];
}
}
@catch (NSException *exception) {
return nil;
}
return entities;
}
@end