Базовые данные -existingObjectWithID: ошибка: вызывает ошибку 133000 - PullRequest
40 голосов
/ 26 декабря 2011

Мое приложение использует Core Data (с некоторой помощью Magical Record) и довольно многопоточное, используя NSOperation.

Конечно, я очень осторожен, чтобы пропустить NSManagedObjectID только между потоками / операциями.

Теперь, чтобы вернуться к соответствующему управляемому объекту в операции, я использую -existingObjectWithID:error: таким образом:

Collection *owner = (Collection *)[localContext existingObjectWithID:self.containerId error:&error];

Но я получаю ноль, и error говорит, что это ошибка # 13300: NSManagedObjectReferentialIntegrityError.

Вот что говорится в документации об этой ошибке:

NSManagedObjectReferentialIntegrityError
Error code to denote an attempt to fire a fault pointing to an object that does not exist.
The store is accessible, but the object corresponding to the fault cannot be found.

Что в моем случае неверно: этот объект существует. Действительно, если я переберу все экземпляры этой Collection сущности с NSFetchRequest, я найду ее среди них, и ее NSManagedObjectID - это именно то, что я передал -existingObjectWithID:error:.

Более того, если я использую -objectWithID: вместо этого, я получаю правильный объект обратно очень хорошо.

Так что я кое-что упускаю. Вот несколько дополнительных замечаний / вопросов:

  • «объект, который не существует»: что означает «существовать» в этом предложении? "существовать" где? В этот момент он определенно «существует» в моем хранилище базовых данных.
  • «объект, соответствующий ошибке, не может быть найден»: что означает «найдено» в этом предложении? "нашел" где? Это определенно «найти» в моем хранилище основных данных в этот момент.

Так, может быть, я что-то упускаю из-за того, что делает existingObjectWithID:error:? В документации сказано:

If there is a managed object with the given ID already registered in the context, that object is returned directly; otherwise the corresponding object is faulted into the context.
[...]
Unlike objectWithID:, this method never returns a fault.

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

  • Какой был бы реалистичный сценарий, ведущий к NSManagedObjectReferentialIntegrityError?

Спасибо за любое просвещение.

Ответы [ 4 ]

38 голосов
/ 20 февраля 2014

Проблема в том, что NSManagedObjectID вы проходите временно. Вы можете проверить это, вызвав метод NSManagedObjectID isTemporaryID. Из документов:

Возвращает логическое значение, которое указывает, является ли получатель временный.

Большинство идентификаторов объектов возвращают NO. Новые объекты вставлены в контексту управляемого объекта назначается временный идентификатор, который заменяется с постоянным, когда объект сохраняется в постоянном хранилище.

Сначала необходимо сохранить изменения в постоянном хранилище , только затем получить постоянный идентификатор для передачи в другой контекст.

8 голосов
/ 27 декабря 2011

Когда вы используете несколько контекстов, вам необходимо убедиться, что вы сохранили контекст A перед передачей идентификатора управляемого объекта из контекста A в другой контекст B. Только после завершения сохранения этот объект будет доступен из контекста B.

-objectWithID: всегда будет возвращать объект, отличный от nil, но он выдаст исключение, как только вы начнете использовать его, если в хранилище нет вспомогательного объекта. -existingObjectWithID:error: фактически запустит некоторый SQL и выполнит ввод / вывод, если этот объект еще не зарегистрирован в контексте, в котором он используется.

2 голосов
/ 15 февраля 2012

NSManagedObjectReferentialIntegrityError = 133000

NSManagedObjectReferentialIntegrityError Код ошибки для обозначения попытки вызвать ошибку, указывающую на объект, который не существует.Магазин доступен, но объект, соответствующий неисправности, не может быть найден.Доступный в Mac OS X v10.4 и позже.Объявлено в CoreDataErrors.h.

См. Эту документацию .

Это руководство может быть полезно для вас.

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

0 голосов
/ 18 октября 2014

Я нашел их при работе с уведомлением NSManagedObjectContextDidSave. Многие объекты, которые были удалены другим контекстом, не могут быть получены, потому что (Дух!) Они были удалены! Однако некоторые из удаленных объектов обнаружились очень хорошо, например, те, которые я уже допустил в текущем контексте.

У вас может быть похожая проблема - объекты, которые вы можете найти при итерации хранилища, могли быть сбиты в этот контекст до того, как они были удалены, и вы либо не объединяете изменения обратно в этот контекст, либо просто не совсем еще объединены.

...