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

Основные данные -existingObjectWithID: ошибка: вызывает ошибку 133000

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

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

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

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

Но то, что я получаю, равно nil и 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?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

NSManagedObjectReferentialIntegrityError = 133000

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

Смотрите documentation.

Этот учебник может быть вам полезен.

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

Ответ 4

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

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