Angenommen, ich habe zwei Entitätsklassen: SocialApp
undSocialAppType
In SocialApp
Ich habe ein Attribut: appURL
und eine Beziehung : type
.
In SocialAppType
Ich habe drei Attribute : baseURL
, name
und favicon
.
Das Ziel der SocialApp
Beziehung type
ist ein einzelner Datensatz in SocialAppType
.
Für mehrere Flickr-Konten gibt es beispielsweise eine Reihe von SocialApp
Datensätzen, wobei jeder Datensatz einen Link zum Konto einer Person enthält. Es würde einen SocialAppType
Datensatz für den Typ "Flickr" geben, auf den alle SocialApp
Datensätze verweisen würden.
Wenn ich eine Anwendung mit diesem Schema erstelle, wird eine Warnung angezeigt, dass zwischen SocialAppType
und keine umgekehrte Beziehung besteht SocialApp
.
/Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse
Benötige ich eine Umkehrung und warum?
quelle
Die Apple-Dokumentation enthält ein hervorragendes Beispiel, das auf eine Situation hinweist, in der Sie möglicherweise Probleme haben, wenn Sie keine umgekehrte Beziehung haben. Lassen Sie es uns in diesen Fall abbilden.
Angenommen, Sie haben es wie folgt modelliert:
Beachten Sie, dass Sie eine Eins-zu-Eins- Beziehung namens " Typ " von
SocialApp
bis habenSocialAppType
. Die Beziehung ist nicht optional und hat eine Löschregel "Verweigern" .Betrachten Sie nun Folgendes:
Wir erwarten, dass das Speichern dieses Kontexts fehlschlägt, da wir die Löschregel auf Verweigern festgelegt haben, während die Beziehung nicht optional ist.
Aber hier gelingt das Speichern.
Der Grund ist, dass wir keine umgekehrte Beziehung festgelegt haben . Aus diesem Grund wird die socialApp-Instanz beim Löschen von appType nicht als geändert markiert. Daher erfolgt vor dem Speichern keine Validierung für socialApp (es wird davon ausgegangen, dass keine Validierung erforderlich ist, da keine Änderung vorgenommen wurde). Aber tatsächlich ist eine Veränderung passiert. Aber es wird nicht reflektiert.
Wenn wir uns an appType von erinnern
appType ist null.
Seltsam, nicht wahr? Wir bekommen Null für ein nicht optionales Attribut?
Sie haben also keine Probleme, wenn Sie die umgekehrte Beziehung eingerichtet haben. Andernfalls müssen Sie die Validierung erzwingen, indem Sie den Code wie folgt schreiben.
quelle
Ich werde die endgültige Antwort umschreiben, die ich in More iPhone 3 Development von Dave Mark und Jeff LeMarche gefunden habe.
Apple empfiehlt im Allgemeinen, dass Sie immer die Umkehrung erstellen und angeben, auch wenn Sie die Umkehrungsbeziehung in Ihrer App nicht verwenden. Aus diesem Grund werden Sie gewarnt, wenn Sie keine Inverse angeben.
Beziehungen sind nicht erforderlich eine inverse haben, denn es gibt einige Szenarien gibt , in denen die inverse Beziehung Performance schaden könnten. Angenommen, die umgekehrte Beziehung enthält eine extrem große Anzahl von Objekten. Das Entfernen des Inversen erfordert das Durchlaufen des Satzes, der die inverse, schwächende Leistung darstellt.
Aber es sei denn , Sie haben einen bestimmten Grund nicht an, die inverse Modell . Es hilft Core Data dabei, die Datenintegrität sicherzustellen. Wenn Sie auf Leistungsprobleme stoßen, ist es relativ einfach, die umgekehrte Beziehung später zu entfernen.
quelle
Die bessere Frage ist: "Gibt es einen Grund, keine Umkehrung zu haben?" Core Data ist wirklich ein Framework zur Verwaltung von Objektgraphen, kein Persistenz-Framework. Mit anderen Worten, seine Aufgabe besteht darin, die Beziehungen zwischen Objekten im Objektdiagramm zu verwalten. Inverse Beziehungen machen dies viel einfacher. Aus diesem Grund erwartet Core Data inverse Beziehungen und ist für diesen Anwendungsfall geschrieben. Ohne sie müssen Sie die Konsistenz des Objektdiagramms selbst verwalten. Insbesondere zu viele Beziehungen ohne umgekehrte Beziehung werden sehr wahrscheinlich durch Kerndaten beschädigt, es sei denn, Sie arbeiten sehr hart, um die Dinge am Laufen zu halten. Die Kosten in Bezug auf die Festplattengröße für die inversen Beziehungen sind im Vergleich zu dem Nutzen, den Sie daraus ziehen, wirklich unbedeutend.
quelle
Es gibt mindestens ein Szenario, in dem ein guter Fall für eine Kerndatenbeziehung ohne Umkehrung gemacht werden kann: Wenn bereits eine andere Kerndatenbeziehung zwischen den beiden Objekten besteht, wird das Objektdiagramm beibehalten.
Beispielsweise enthält ein Buch viele Seiten, während sich eine Seite in einem Buch befindet. Dies ist eine wechselseitige Viele-zu-Eins-Beziehung. Durch das Löschen einer Seite wird nur die Beziehung ungültig, während durch das Löschen eines Buches auch die Seite gelöscht wird.
Möglicherweise möchten Sie jedoch auch die aktuell gelesene Seite für jedes Buch verfolgen. Dies könnte mit einer „current“ erfolgen Eigenschaft auf Seite , aber dann müssen Sie eine andere Logik , um sicherzustellen , dass nur eine Seite im Buch wie die aktuelle Seite jederzeit markiert. Wenn Sie stattdessen eine currentPage- Beziehung von Book zu einer einzelnen Seite herstellen, wird sichergestellt, dass immer nur eine aktuelle Seite markiert ist. Außerdem kann mit einfach book.currentPage problemlos auf diese Seite mit einem Verweis auf das Buch zugegriffen werden.
Wie wäre die wechselseitige Beziehung in diesem Fall? Etwas weitgehend Unsinniges. "myBook" oder ähnliches könnte wieder in die andere Richtung hinzugefügt werden, enthält jedoch nur die Informationen, die bereits in der "Buch" -Beziehung für die Seite enthalten sind, und schafft so eigene Risiken. Möglicherweise wird in Zukunft die Art und Weise, wie Sie eine dieser Beziehungen verwenden, geändert, was zu Änderungen in Ihrer Kerndatenkonfiguration führt. Wenn page.myBook an einigen Stellen verwendet wurde, an denen page.book im Code hätte verwendet werden sollen, können Probleme auftreten. Eine andere Möglichkeit, dies proaktiv zu vermeiden, besteht darin, myBook nicht in der NSManagedObject-Unterklasse verfügbar zu machen, die für den Zugriff auf die Seite verwendet wird. Es kann jedoch argumentiert werden, dass es einfacher ist, das Inverse überhaupt nicht zu modellieren.
In dem beschriebenen Beispiel sollte die Löschregel für die currentPage-Beziehung auf "No Action" oder "Cascade" gesetzt werden, da keine wechselseitige Beziehung zu "Nullify" besteht. (Cascade impliziert, dass Sie beim Lesen jede Seite aus dem Buch herausreißen. Dies kann jedoch der Fall sein, wenn Sie besonders kalt sind und Kraftstoff benötigen.)
Wenn gezeigt werden kann, dass die Integrität von Objektgraphen nicht gefährdet ist, wie in diesem Beispiel, und die Komplexität und Wartbarkeit des Codes verbessert wird, kann argumentiert werden, dass eine Beziehung ohne Inverse die richtige Entscheidung sein kann.
quelle
currentPage
markiert werden alsOptional
?Während die Dokumente keine Umkehrung zu erfordern scheinen, habe ich gerade ein Szenario gelöst, das tatsächlich zu "Datenverlust" führte, indem ich keine Umkehrung hatte. Ich habe ein Berichtsobjekt, das eine Beziehung zu vielen zu meldepflichtigen Objekten hat. Ohne die umgekehrte Beziehung gingen alle Änderungen an der zu vielen Beziehung beim Neustart verloren. Nach der Überprüfung des Core Data-Debugs stellte sich heraus, dass die Aktualisierungen des Objektdiagramms (der Beziehungen) trotz des Speicherns des Berichtsobjekts nie vorgenommen wurden. Ich habe eine Umkehrung hinzugefügt, obwohl ich sie nicht benutze, und voila, sie funktioniert. Es kann also nicht heißen, dass es erforderlich ist, aber Beziehungen ohne Umkehrungen können definitiv seltsame Nebenwirkungen haben.
quelle
Inverse werden auch verwendet für
Object Integrity
(aus anderen Gründen siehe die anderen Antworten):Von: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html#//apple_ref/doc/uid/TP40001075-CH17-SW1
Der bereitgestellte Link gibt Ihnen Ideen, warum Sie ein
inverse
Set haben sollten . Ohne sie können Sie Daten / Integrität verlieren. Auch die Wahrscheinlichkeit, dass Sie auf ein Objekt zugreifen, istnil
wahrscheinlicher.quelle
Es besteht im Allgemeinen keine Notwendigkeit für eine umgekehrte Beziehung. Es gibt jedoch nur wenige Macken / Fehler in den Kerndaten, bei denen Sie eine umgekehrte Beziehung benötigen. Es gibt Fälle, in denen Beziehungen / Objekte verloren gehen, obwohl beim Speichern des Kontexts kein Fehler auftritt, wenn eine umgekehrte Beziehung fehlt. Überprüfen Sie dieses Beispiel , das ich erstellt habe, um zu demonstrieren, dass Objekte fehlen und wie Sie das Problem umgehen können, während Sie mit Kerndaten arbeiten
quelle