OK, das macht mich verrückt.
Ich habe zwei Threads, die ein UImanaged Dokument verwenden, eines für den Hauptkontext, in dem der Benutzer eine Auswahl trifft, der Hintergrundthread mit seinem eigenen moc synchronisiert die Daten mit einem Server entsprechend den Zeitstempeln.
Alles scheint gut zu funktionieren, aber wenn ich: 1. Fügen Sie ein Objekt zum Hauptkontext hinzu 2. Synchronisieren im Hintergrund 3. Vom Hintergrund speichern 4. Versuchen Sie, das gleiche Objekt erneut zu ändern, jetzt aus dem Hauptkontext - Haupt-Thread
Ich bekomme ein NSMergeConflict
Ich werde einen Code von mir mit einbeziehen, der eine Menge irrelevanten Code enthält, um Ihnen zu zeigen, wie ich die Kontexte initialisiere, hoffentlich kann mich jemand aufklären. Ich weiß, Kerndaten sind in diesen Bereichen schwierig.
Im Hauptthread (in applicationdidfinishloadingwithoptions):
%Vor%Und später:
%Vor%Und im Hintergrund:
%Vor%Ich habe alle Arten von Merge-Policy-Konstanten vergeblich versucht.
Ich bekomme das und die Datei wird nicht gespeichert:
conflictList = ( "NSMergeConflict (0x1a9ee1e0) für NSManagedObject (0x119aea80) mit objectID '0x9dcec90' mit oldVersion = 10 und newVersion = 11 und alter Objekt-Snapshot = {\ n displayName = \" \ "; \ n machineName = KIYGRDRTTDVLTQB; \ n Hinweis = \" \ "; \ n product = \" 0x11967ab0 \ "; \ n public = 1; \ n veröffentlicht = 1; \ n Menge = 3; \ n registeredTo = \" \ "; \ n registeredToEmail = \" \ "; \ n registeredToNote = \ "\"; \ n status="AUF REGISTRIERUNG"; \ n upDate = \ "2013-03-07 10:22:01 +0000 \"; \ n wishList = \ "\"; \ n} und neue zwischengespeicherte Zeile = {\ n displayName = \ "\"; \ n machineName = KIYGRDRTTDVLTQB; \ n Hinweis = \ "\"; \ n Produkt = \ "0x1a9ee3d0 \"; \ n public = 1; \ n published = 1; \ n Menge = 3; \ n registeredTo = \ "\"; \ n registeredToEmail = \ "\"; \ n registriertZuNote = \ "\"; \ n status = \ "ON REGISTRY \"; \ n upDate = \ "2013-03-07 10:22:03 +0000 \"; \ n wishList = \ "\"; \ n} " ); }
Übrigens ist der einzige Unterschied zwischen den alten und neuen Objekten ein Zeiger auf "Produkt". Könnte das vielleicht mein Problem sein?
Ein weiterer möglicher Hinweis ist die Tatsache, dass dies nur bei neu hinzugefügten Objekten geschieht und erst NACH der Hintergrundsynchronisation erfolgt. Wenn ich die App stoppe und neu lade (den persistenten Speicher neu lade), kann ich das existierende Objekt jetzt problemlos bearbeiten und es beliebig oft synchronisieren.
Danke Leute
OK Freunde,
Nach einem Monat, in dem ich meine Gedanken darüber gebrochen habe - gibt es eine Lösung und nichts, was ich hätte erraten können. Ich habe tatsächlich einen Support-Vorfall mit Apple eröffnet und sie haben das gelöst.
Also hier geht es:
Beim Festlegen der Zusammenführungsrichtlinie für den Kontext des verwalteten Hauptobjekts gibt es eine Eigenschaft namens parentContext. Es ist mir immer noch nicht ganz klar, um was es sich handelt, da die Dokumentation diesbezüglich knapp ist. Dies löst jedoch definitiv mein Problem. Bitte beachten Sie, dass ich in meinem Workflow ein NSManagedDocument erstelle und den Kontext daraus extrahiere. Ich denke, die meisten Leute machen es andersherum (die meisten verwenden kein verwaltetes Dokument).
Anstelle von
%Vor%Ich benutze jetzt:
%Vor%Die Block-Sache ist eine Vorsichtsmaßnahme, um sicherzustellen, dass dies im richtigen Thread ausgeführt wird. Wichtig ist, dass die Zusammenführungsrichtlinie auf den parentContext des gewünschten Kontexts festgelegt wird.
Auf eine persönliche Anmerkung muss ich zwei große Buhs hinzufügen: 1. Boo zu mir, für die Verwendung von NSManagedDocument, obwohl es ein wenig veraltet ist, nur weil ich gute Beispiele dafür gefunden habe. 2. Big Boo zu Apple für sehr fehlende Dokumentation auf dem Gebiet. Ich habe wochenlang über ManagedObjectContexts gelesen und war heute meine erste Bekanntschaft mit der Eigenschaft parentContext.
Tags und Links multithreading ios core-data cocoa-touch conflict