Допустим, у меня есть два класса сущностей: SocialApp
иSocialAppType
В У SocialApp
меня есть один атрибут: appURL
и одно отношение: type
.
В У SocialAppType
меня есть три атрибута: baseURL
, name
и favicon
.
Пункт назначения SocialApp
отношений type
- одна запись в SocialAppType
.
Например, для нескольких учетных записей Flickr будет несколько SocialApp
записей, каждая из которых будет содержать ссылку на учетную запись человека. Для SocialAppType
типа «Flickr» будет одна запись, на которую SocialApp
будут указывать все записи.
Когда я создаю приложение с этой схемой, я получаю предупреждение об отсутствии обратной зависимости между SocialAppType
и SocialApp
.
/Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse
Нужно ли обратное и почему?
источник
В документации Apple есть отличный пример, который предлагает ситуацию, в которой у вас могут возникнуть проблемы из-за отсутствия обратной связи. Давайте сопоставим это в этом случае.
Предположим, вы смоделировали это следующим образом:
Обратите внимание, что у вас есть отношение « один к одному», называемое « тип », от
SocialApp
доSocialAppType
. Отношения не являются необязательными и имеют «запрещающее» правило удаления .Теперь рассмотрим следующее:
Мы ожидаем неудачного сохранения этого контекста, поскольку мы установили правило удаления как Запретить, в то время как отношения не являются обязательными.
Но здесь сохранение удается.
Причина в том, что мы не установили обратную связь . Из-за этого экземпляр socialApp не помечается как измененный при удалении appType. Таким образом, проверка достоверности для socialApp перед сохранением не происходит (предполагается, что проверка не требуется, поскольку никаких изменений не произошло). Но на самом деле произошли изменения. Но это не отражается.
Если мы вспомним appType от
appType равен нулю.
Странно, не правда ли? Мы получаем ноль для необязательного атрибута?
Таким образом, у вас нет проблем, если вы установили обратные отношения. В противном случае вы должны выполнить принудительную проверку, написав код следующим образом.
источник
Я перефразирую окончательный ответ, который я нашел в More iPhone 3 Development от Dave Mark и Jeff LeMarche.
Apple обычно рекомендует всегда создавать и указывать обратное, даже если вы не используете обратное отношение в своем приложении. По этой причине он предупреждает вас, если вы не предоставите обратное.
Отношения не обязательно должны иметь обратную зависимость, поскольку существует несколько сценариев, в которых обратная зависимость может снизить производительность. Например, предположим, что обратное отношение содержит чрезвычайно большое количество объектов. Удаление обратного требует итерации по набору, который представляет обратную, ослабляющую производительность.
Но если у вас нет конкретной причины не делать этого, смоделируйте обратное . Это помогает Core Data обеспечить целостность данных. Если у вас возникнут проблемы с производительностью, обратное отношение будет относительно легко удалить позже.
источник
Лучший вопрос: есть ли причина не иметь обратного? Core Data на самом деле является структурой управления графами объектов, а не структурой постоянства. Другими словами, его работа заключается в управлении отношениями между объектами в графе объектов. Обратные отношения делают это намного проще. По этой причине Core Data ожидает обратных связей и написана для этого варианта использования. Без них вам придется самостоятельно управлять согласованностью графов объектов. В частности, к-многим без обратной связи, очень вероятно, будут повреждены Core Data , если вы работаете очень трудно держать вещи работать. Стоимость с точки зрения размера диска для обратных связей действительно незначительна по сравнению с выгодой, которую она вам приносит.
источник
Существует, по крайней мере, один сценарий, в котором можно привести хороший пример отношения ядра с данными без обратного: когда уже есть другое отношение ядра данных между двумя объектами, которое будет обрабатывать поддержание графа объектов.
Например, книга содержит много страниц, в то время как страница находится в одной книге. Это двусторонние отношения многие-к-одному. Удаление страницы просто аннулирует отношения, тогда как удаление книги также удалит страницу.
Тем не менее, вы также можете отслеживать текущую страницу для каждой книги. Это можно сделать с помощью свойства «currentPage» на странице , но тогда вам понадобится другая логика, чтобы гарантировать, что только одна страница в книге будет помечена как текущая страница в любое время. Вместо этого создание отношения currentPage из Book на одну страницу гарантирует, что всегда будет помечена только одна текущая страница, и, кроме того, к этой странице можно легко получить доступ со ссылкой на книгу просто с book.currentPage.
Какими будут взаимные отношения в этом случае? Что-то в значительной степени бессмысленное. «myBook» или подобное может быть добавлено обратно в другом направлении, но оно содержит только информацию, уже содержащуюся в связи «book» для страницы, и, таким образом, создает свои собственные риски. Возможно, в будущем способ использования одного из этих отношений изменится, что приведет к изменениям в конфигурации ваших основных данных. Если page.myBook использовался в некоторых местах, где page.book должен был использоваться в коде, могут возникнуть проблемы. Другим способом предотвращения этого также было бы не показывать myBook в подклассе NSManagedObject, который используется для доступа к странице. Тем не менее, можно утверждать, что проще не моделировать обратное в первую очередь.
В приведенном примере правило удаления для отношения currentPage должно быть установлено на «No Action» или «Cascade», так как нет обратной связи для «Nullify». (Каскад подразумевает, что вы вырываете каждую страницу из книги, когда читаете ее, но это может быть правдой, если вам особенно холодно и вам нужно топливо.)
Когда можно продемонстрировать, что целостность графов объектов не подвергается риску, как в этом примере, и улучшена сложность и удобство сопровождения кода, можно утверждать, что отношение без обратного может быть правильным решением.
источник
currentPage
пометить какOptional
?В то время как документы, кажется, не требуют обратного, я только решил сценарий, который фактически привел к "потере данных", не имея обратного. У меня есть объект отчета, который имеет отношение ко многим в отчетных объектах. Без обратной связи любые изменения в отношении ко многим были потеряны при перезапуске. После проверки отладки Core Data стало очевидно, что даже при сохранении объекта отчета обновления графа объектов (отношений) никогда не производились. Я добавил обратное, хотя я им не пользуюсь, и вуаля, это работает. Таким образом, он может не сказать, что это необходимо, но отношения без инверсий могут иметь странные побочные эффекты.
источник
Инверсы также используются для
Object Integrity
(по другим причинам, см. Другие ответы):От: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html#//apple_ref/doc/uid/TP40001075-CH17-SW1
Приведенная ссылка дает вам идеи, почему вы должны иметь
inverse
набор. Без этого вы можете потерять данные / целостность. Кроме того, вероятность того, что вы получите доступ к объекту, которыйnil
является более вероятным.источник
Как правило, нет необходимости в обратных отношениях. Но в Базовых данных есть несколько причуд / ошибок, когда вам нужны обратные отношения. Существуют случаи, когда отношения / объекты пропадают, даже если при сохранении контекста не возникает ошибки, если отсутствуют обратные отношения. Посмотрите на этот пример , который я создал, чтобы продемонстрировать отсутствие объектов и способы их обхода при работе с основными данными.
источник