Основные данные -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
?
Спасибо за любое просвещение.
Ответы
Ответ 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. Многие объекты, удаленные другим контекстом, не могли быть извлечены, потому что (Ду!) Они были удалены! Однако некоторые из удаленных объектов выглядели просто отлично, как те, которые я уже винил в текущем контексте.
У вас может быть аналогичная проблема - объекты, которые вы можете найти, когда вы перебираете хранилище, возможно, были повреждены в этом контексте до того, как они были удалены, и вы либо не объединяете изменения в этот контекст, либо просто не совсем но объединены.