2016-04-15 10 views
4

Ich führe Unique Constraints zu einer bestehenden App, in einer neuen Modellversion.Core Data Unique Constraints - "Dangling Verweis auf ein ungültiges Objekt" auf Speichern

Das Modell hat die Entität Person, die eine optionale Eins-zu-Eins-Beziehung mit Entität Pet hat. Die Löschregel der Person ist eine Kaskade, und die Regel zum Löschen der umgekehrten Beziehung von Pet wird aufgehoben. Es gibt eine andere Entität, Job, bei der Person auch eine direkte Beziehung hat. Diese Löschregel und die Regel für die inverse Löschung werden jedoch beide aufgehoben.

Person hat eine "personID" -Eigenschaft, die ich einzigartig gemacht habe.

In einem Hauptwarteschlangenkontext habe ich eine Instanz von Person mit ID xxx, die kein Pet-Set hat. Lassen Sie uns diese Person "Charlie" nennen. Ich erstelle auch einen Job und stelle ihn als "iOS Dev" ein und weise ihn Charlie's Job-Eigenschaft zu.

Dann in einen Child Private Queue-Kontext, ich füge ein neues "Charlie" auch mit ID xxx (die einzigartige Einschränkung) und erstellen Sie ein Pet und legen Sie es fest. Ich stelle keinen Job ein. Ich speichere den Child-Kontext ohne Probleme.

Unmittelbar danach versuche ich den Hauptwarteschlangenkontext zu speichern. Aber kurz zuvor prüfe ich die Eigenschaft insertedObjects des Hauptwarteschlangenkontextes und sehe erwartungsgemäß eine Instanz von Person mit ID xxx. Was ich erwarte, ist, dass diese zweite Instanz von eindeutigen Einschränkungen gehandhabt wird und mit der ursprünglichen Instanz von Person aus dem vorherigen Absatz "verschmolzen" wird. Aber, wenn ich das Speichern des MOC tatsächlich aufrufen: Methode, wirft es eine Ausnahme und ich inspizieren das NSError Objekt:

Fehler Domain = NSCocoaErrorDomain-Code = 1550 „Die Operation nicht abgeschlossen sein könnte (Cocoa Fehler 1550. zu einem ungültigen Objekt.)“Userinfo = {Schlenker Referenz. = null

Irgendwelche Ideen, wie die Ausnahme zu vermeiden? Ich bin es gewohnt, in Core Data "Dangling Referenzen" zu haben, was bedeutet, dass eine Beziehung falsch konfiguriert ist, aber ich habe es einige Male durchgelesen und es sieht gut aus, also bin ich mir nicht sicher, was ich sonst noch angehen sollte. Ich verwende alle Kontexte, die die NSMergeByPropertyObjectTrompMergePolicy-Merge-Richtlinie verwenden.

Offensichtlich ist dies ein wenig schwer zu folgen, so warf ich ein Beispielprojekt auf Github, falls jemand up interessiert: https://github.com/bpapa/core-data-unique-bug

Antwort

4

Ich beendete das Brennen eines Code-Level-Support-Tickets auf diesem, und ein Apple-Ingenieur bestätigte, dass es einen Fehler gibt. Als Workaround wurde empfohlen, eine eigene Zusammenführungsrichtlinie zu schreiben, die super aufruft und dann manuell sicherstellt, dass die Beziehung an beiden Enden eingestellt ist.

+0

In meinem Fall hat ein Upgrade auf Xcode 8.2 das Problem verschwinden lassen! – bruce1337

+0

Das ist gut zu hören. In meiner App habe ich festgestellt, dass das Schreiben meiner eigenen Merge-Richtlinie das Problem nicht gelöst hat. Deshalb habe ich mich einfach von der Unique-Funktion entfernt, die viel zusätzlichen Code zum Erstellen oder Aktualisieren erfordert und sich auch anstellen muss meine Operationen, die in Kerndaten speichern. Hoffentlich kann ich das irgendwann noch einmal Revue passieren lassen. – bpapa

+0

Ich muss meinen freudigen Kommentar vom 29. Oktober zurückziehen - dieses Problem ist mit einer Rache zurückgekommen und ich glaube jetzt, dass der 1550-Dangling-Referenzfehler nur scheinbar verschwunden zu sein schien, weil ich den Inhalt auf dem Simulator zurückgesetzt hatte. In meinem Fall erhalte ich 1550, wenn mein Inhalt vom Server aktualisiert wird und meine App versucht, vorhandene Objekte in Core Data zu aktualisieren. Ich benutze jetzt Release-Version 8.2 und versuche immer noch, mein Problem zu lösen, vorausgesetzt, es ist immer noch nicht aufgrund eines Fehlers in Xcode. – bruce1337

1

Wenn Sie die neue iOS 9 Einzigartige Constrains Strategie einsetzen wollen, müssen Sie sicherstellen, sicher, dass beide Kontexte haben die gleiche Merge-Richtlinie festgelegt.

Hinweis, dass dies nicht Ihnen helfen, wenn Sie ein Szenario, in dem die aktuelle Instanz des Objekts ein Attribut/Beziehung hat, die nil und Ihre Absicht ist es, immer „erweitern“ das Objekt, also füllen Sie alle fehlenden Attribute und bestehende aktualisieren.

Ansonsten gilt für Pre-iOS9 Folgendes.

Vielleicht gibt es einige Missverständnisse über die Bedeutung der Merge-Richtlinie, die Sie verwenden (NSMergeByPropertyObjectTrumpMergePolicy). Es bezieht sich auf eine Situation, in der Sie eine Version eines Objekts im Speicher und eine andere im permanenten Speicher haben, nicht zwei Versionen im Speicher in verschiedenen Kontexten. Von den Header-Dateien:

Diese Singleton-Richtlinie führt Konflikte zwischen der Version des persistenten Speichers des Objekts und der aktuellen Version im Speicher zusammen.

So wird Ihr Prozess neues Objekt zu schaffen, ist nicht der richtige Ansatz.

Stattdessen sollten Sie die Person im untergeordneten Kontext mit der eindeutigen ID abrufen.

Alternativ können Sie das Objekt objectID (ein undurchsichtiges Core Data-Artefakt) für den untergeordneten Kontext verfügbar machen, um eine Referenz auf dasselbe Objekt im Objektdiagramm mit objectWithID: zu erhalten.

+0

Aber ich dachte, der ganze Zweck der Unique Constraints in iOS 9 ist, dass ich nicht zu einem "fetch oder create" Art von Ding? Ich mache das, um Duplikate von Datensätzen zu vermeiden, die in einem anderen Thread erstellt werden könnten, was meiner Meinung nach eines der Probleme war, die Unique Constraints lösen sollte. – bpapa

+0

OK - Ich sehe, woher du kommst. Sie müssen die Zusammenführungsrichtlinie für * beide Kontexte * festlegen, andernfalls wird es nicht funktionieren. Ich bevorzuge es immer noch, an demselben verwalteten Objekt zu arbeiten, anstatt mich auf eine eher intransparente Verschmelzungsstrategie zu verlassen (weil sie expliziter und debuggbar ist), aber Ihr Ansatz sollte auch funktionieren. – Mundi

+0

Es sollte! Ich setze die Zusammenführungsrichtlinie in allen hier betroffenen Kontexten. Ich bin mir ziemlich sicher, dass dies an dieser Stelle ein Apple-Bug ist, aber untersuchen wird. – bpapa

0

Fügen Sie die Änderungen in den Hauptkontext ein, indem Sie die Benachrichtigung zum Speichern aus dem Hintergrundkontext verwenden. Siehe Apples Earthquakes-Beispiel.