Ответ 1
Вот что вам нужно сделать, чтобы правильно объединить контексты. Во-первых, вам не нужно ваше собственное уведомление. Выполнение операции сохранения в контексте автоматически направляет следующее уведомление зарегистрированным наблюдателям:
NSManagedObjectContextDidSaveNotification
Поэтому все, что вам нужно сделать, это:
1) в вашем основном потоке, может быть в методе viewDidLoad
, зарегистрируйтесь для этого уведомления:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
2) реализуем метод contextDidSave:
в основном потоке следующим образом:
- (void)contextDidSave:(NSNotification *)notification
{
SEL selector = @selector(mergeChangesFromContextDidSaveNotification:);
[managedObjectContext performSelectorOnMainThread:selector withObject:notification waitUntilDone:YES];
}
3) в вашем методе dealloc
добавьте следующее:
[[NSNotificationCenter defaultCenter] removeObserver:self];
4) создайте новый контекст в другом потоке, используя что-то вроде следующего метода:
- (NSManagedObjectContext*)createNewManagedObjectContext
{
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
[moc setUndoManager:nil];
return [moc autorelease];
}
5) после получения новых данных надлежащим способом справиться с этой ситуацией является использование идентификаторов управляемых объектов. Поскольку идентификаторы управляемых объектов являются потокобезопасными, вы можете передать их из основного потока в другой поток, а затем использовать existingObjectWithID:error:
для извлечения объекта, связанного с конкретным идентификатором, обновления и сохранения контекста. Теперь слияние будет действовать, как вы ожидаете. В качестве альтернативы, если вы заранее не знаете, какие идентификаторы управляемых объектов должны быть переданы между потоками, то в другом потоке вы просто извлекаете объекты с использованием предиката для получения тех, которые соответствуют объектам, полученным с сервера, затем вы их обновляете и сохраните контекст.