Подтвердить что ты не робот

CoreData: "Висячая ссылка на недопустимый объект". ошибка

Я работаю над приложением Cocoa -Touch, он использует CoreData и имеет некоторые подклассы NSPersistentObject, созданные редактором модели XCode.

Я заметил, что в последнее время при сохранении контекста я получаю сообщение об ошибке, которое имеет в качестве информации пользователя следующую часть:

(gdb) po ui {
    "Dangling reference to an invalid object." = <null>;
    NSAffectedObjectsErrorKey = <dump #1 of someObject>;
    NSLocalizedDescription = "Operation could not be completed. (Cocoa error 1550.)";
    NSValidationErrorKey = <someKey pointing to someObject #1>;
    NSValidationErrorObject = <dump #2 of someOtherObject which points to the dump #1 object>;
    NSValidationErrorValue = { <list of someMoreObjects> };
}

В словаре пользовательской информации есть другие ключи.

Все дампы, которые я получаю, являются допустимыми объектами, я проверил их все.

NSValidationErrorObject - это объект, который имеет NSSet, который содержит объекты типов, сбрасываемых в NSAffectedObjectsErrorKey и NSValidationErrorValue. Но все эти объекты действительны.

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

Я не знаю, почему это происходит, или что именно происходит с ошибкой. Кто-нибудь знает, что происходит? Любые идеи, которые могут вызвать эту странную ошибку?

4b9b3361

Ответ 1

Эта ошибка обычно возникает из-за того, что отношения устанавливаются неправильно часто, когда объект остается без необходимых взаимных отношений. Объект "свисает", потому что граф объекта говорит, что он должен находиться в отношениях, но он просто висит в пространстве, не связанном с каким-либо другим объектом. Объект по-прежнему действует в том смысле, что он является внутренним, но он не находится в допустимом месте на графике.

Ответ 2

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

Ищите проблемы с потоками, если вы делаете что-либо с потоком с Core Data.

Ответ 3

Скажем, у вас есть таблица "рецепты" и дочерняя таблица "ингредиенты". Затем вы создаете отношение "один ко многим" от рецепта к ингредиентам, а также создаете обратную взаимосвязь (один к одному) от ингредиентов к рецептам. Имеет смысл указать правило удаления "каскада" из таблицы рецептов, потому что, если вы удаляете рецепт, ингредиент также должен быть удален. Тем не менее, если вы укажете "no action" в правиле удаления в отношении отношения "один к одному" в ингредиентах, вы получите ошибку оборванных ссылок при попытке удалить ингредиент. Измените правило удаления для отношения "один-к-одному" к "nullify", и это должно устранить проблему.

Ответ 4

Я знаю это задолго до того факта, но я боролся с этой проблемой в базовой модели данных, у которой ВСЕ отношения установлены на Nullify. Удерживая эти болтающиеся ссылки, пока я не нашел один setPrimitiveValue вместо setValue, когда добавлял к отношениям. Будьте осторожны, с отношениями, вы должны быть уверены, что делаете правильные вещи, чтобы позволить Core Data поддерживать отношения для вас!

Ответ 5

У меня есть еще один пример того, как вызвать эту проблему: у меня есть MOC с типом concurrency NSMainQueueConcurrencyType. Где-то в коде я делаю это:

__block MyObjectType1 *obj1;
[managedObjectContext performBlockAndWait:^{
    obj1 = [NSEntityDescription insertNewObjectForEntityForName:@"Thing" inManagedObjectContext:managedObjectContext];
}];
// some other stuff
[self saveContext];
__block NSManagedObjectID *object1ID;
[managedObjectContext performBlockAndWait:^{
    object1ID = [obj1 objectID];
}];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // do some slow-ish stuff
    [managedObjectContext performBlockAndWait:^{
        // create new object that has a relationship
        NSManagedObject *obj1_copy = [managedObjectContext objectWithID:object1ID];
        MyObjectType2 *obj2 = [NSEntityDescription insertNewObjectForEntityForName:@"OtherThing" inManagedObjectContext:managedObjectContext];
        obj2.relatedThing = obj1_copy;
    }];
    [self saveContext];
});

Оказывается, иногда это терпит неудачу. Я все еще не понимаю, почему, но заставить заставить не-временный objectID, похоже, сделать трюк:

[context performBlockAndWait:^{
    NSError *error;
    [managedObjectContext obtainPermanentIDsForObjects:@[obj1] error:&error];
    object1ID = obj1.objectID;
}];

Ответ 6

У меня была та же проблема, и, наконец, я обнаружил, что проблема заключалась в том, что я устанавливал связь между двумя различными контекстами управляемых объектов.

Ответ 7

Моя проблема была решена с помощью этого кода:

[[CustomManagedObject managedObjectContext] performBlockAndWait:^{
        NSError *error;
        if (![[CustomManagedObject managedObjectContext] save:&error])
        {
            NSLog(@"Error in Saving: %@", [error.userInfo description]);
        }
    }];

Ответ 8

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

Ответ 9

Я столкнулся с этой проблемой, и проблема была связана с различными (или, скорее, нулевыми) контекстами управляемых объектов для объектов, у которых были отношения. В моем случае я создал связь между сущностями, когда у обоих были nil Contexts управляемых объектов, а затем добавлено одно из объектов в MOC и предполагается, что другое будет добавлено в MOC. Я предположил это из-за первых двух комментариев в верхнем ответе на этот поток SO, но это оказалось неправильным.

Итак, извлеченный урок: если вы добавите объект в MOC, другие объекты, у которых есть отношения к нему, не будут втягиваться в MOC вместе с ним. Вы должны добавить их в MOC, или Core Data не будет счастлив.