Ошибка при удалении объекта Core Data: NSManagedObjectContext не может удалить объекты в других контекстах - PullRequest
2 голосов
/ 13 июня 2011

Я столкнулся с проблемой при попытке удалить объект из моего основного хранилища данных. Ошибка, которую я получаю при вызове deleteOject, выглядит следующим образом: An NSManagedObjectContext cannot delete objects in other contexts.

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

Код, с которым я тестирую, находится ниже:

NSMutableSet *remoteNids = [NSMutableSet setWithObjects:@"140", @"141", nil];
for (GCEvent *event in nodeEventsFromStore) {
    if (![remoteNids containsObject:event]) {
        NSLog(@"Event no longer exists on remote. Removing object %@ from store.", event);
        [[delegate managedObjectContext] deleteObject:event];
    }
    else {
        NSLog(@"Event %@ exists on remote", event);
    }
}

Ответы [ 2 ]

5 голосов
/ 17 июня 2011

Маловероятно, что базовые данные вам лгут. Я бы посоветовал добавить в ваш код assert:

NSAssert([delegate managedObjectContext] == [event managedObjectContext], @"Found two contexts: %@ and %@", [delegate managedObjectContext, [event managedObjectContext]);

Запустите ваше приложение через Xcode с включенными точками останова (чтобы оно разрывалось при нажатии на утверждение) и установите MallocStackLoggingNoCompact = YES.

Когда запускается assert, вы можете использовать консоль gdb следующим образом:

(gdb) info malloc [address of event's MOC]
(gdb) info malloc [address of delegate MOC]

Это напечатает трассировку стека alloc и покажет вам, где вы создали два moc's.

1 голос
/ 14 июня 2011

Самый простой способ устранения неполадок - это зарегистрировать контекст управляемого объекта, а затем свойство managedObjectContext каждого объекта GCEvent перед его удалением. Если ошибка верна, адрес двух контекстов не будет совпадать. Если у вас нет множественного контекста, то свойство managedObjectContext каждого GCEvent, скорее всего, nil.

Вы можете получить эту ошибку, если вы инициализируете управляемый объект непосредственно, то есть с помощью alloc-init, но затем никогда не назначаете его контексту, устанавливая его свойство managedObjectContext в контекст. Контекст управляемого объекта будет обрабатывать любое значение, кроме себя, как другой контекст, даже если это нулевое значение.

...