Основные данные: оператор все еще активен
В моем приложении появляется следующая ошибка:
CoreData: ошибка: серьезная ошибка приложения. Исключено во время обработки изменения основных данных. Обычно это ошибка в наблюдатель NSManagedObjectContextObjectsDidChangeNotification. оператор по-прежнему активен с userInfo (null)
Все, что я могу найти, по-видимому, указывает на то, что у меня могут быть проблемы с несколькими потоками с моим основным объектом, управляемым данными, но я не могу найти нигде в своем приложении, где это будет так. Я просматриваю и управляю контекстом управляемого объекта в фоновом потоке. Контекст - это только выборка и манипулирование объектами в этом фоновом потоке. Когда я обнаруживаю, что сохраняет этот контекст с помощью NSManagedObjectContextObjectsDidSaveNotification, я объединяю изменения в другой контекст, который я получаю только в своем основном потоке. Когда я делаю вызов для слияния изменений, возникает ошибка. Очень редко это происходит даже при тех же наборах данных.
Я где-то читал, что можно "включить многопоточные утверждения", используя "-com.apple.CoreData.ThreadingDebug 3", но я не смог заставить это работать.
Кто-нибудь знает возможно ли это? Я надеялся, что это может привести к некоторым утверждениям, которые помогут мне найти, где я играю с контекстом в неправильном потоке или что-то в этом роде.
Любые другие подсказки о том, что может произойти, или как отследить эту проблему?
Ответы
Ответ 1
У меня была аналогичная проблема и нашел способ ее решить.
Я создал механизм, создающий различные контексты на основе имен потоков (1 поток = 1 контекст).
#include <pthread.h>
...
mach_port_t threadID = pthread_mach_thread_np(pthread_self());
NSString *threadName = [NSString stringWithFormat:@"%x", threadID];
NSManagedObjectContext *context = [singleton.threadsContexts objectForKey:threadName];
if (!context) {
NSLog(@"Creating managed context for thread named '%@'", threadName);
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[singleton.managedObjectContext persistentStoreCoordinator]];
//initialize dictionary in your singleton if it as not been yet
if(!singleton.threadsContexts)
{
singleton.threadsContexts = [NSMutableDictionary new];
}
[singleton.threadsContexts setObject:context forKey:threadName];
}
return result;
а затем, когда мне нужна полная версия управляемого объекта в фоновом потоке, я получаю копию объекта, выделенного для этого потока:
NSManagedObjectModel *myNewObject = [myBackgroundContext objectWithID:[myObject objectID]];
Надеюсь, что этот ответ поможет.