Wie teile ich einen Core Data Store zwischen Prozessen mit NSDistributedNotifications?

8

Hintergrund

Ich habe bereits eine Frage zu den Grundlagen von Freigabe eines Core Data Store zwischen Prozessen .

Ich versuche, die gegebenen Empfehlungen umzusetzen, und ich stoße auf Probleme.

Mein Ziel

Ich habe zwei Prozesse - die Helfer-App und die Benutzeroberfläche. Sie teilen sich einen einzigen Datenspeicher. Ich möchte, dass die Benutzeroberfläche ihren NSManagedObjectContext aktualisiert, wenn die Helper-App neue Daten im Speicher gespeichert hat.

Aktueller Programmablauf

  1. Der Helper-App-Prozess schreibt Daten in den Speicher.

  2. In der Helper-App höre ich nach NSManagedObjectContextDidSaveNotification-Benachrichtigungen.

  3. Wenn der Kontext gespeichert wird, kodiere ich die eingefügten, gelöschten und aktualisierten Objekte mithilfe ihrer URI-Repräsentationen und NSArchiver.

  4. Ich sende eine NSNotification an das NSDistributedNotificationCenter mit diesem codierten Wörterbuch als userInfo.

  5. Der UI-Prozess wartet auf die Speicherbenachrichtigung. Wenn die Benachrichtigung empfangen wird, wird die Benutzerinfo mit NSUnarchiver entpackt.

  6. Es werden alle aktualisierten / eingefügten / gelöschten Objekte aus den angegebenen URIs gesucht und durch NSManagedObjects ersetzt.

  7. Er erstellt eine NSNotification mit den aktualisierten / eingefügten / gelöschten Objekten.

  8. Ich rufe mergeChangesFromContextDidSaveNotification auf: Führe im Kontext des verwalteten Objekts des UI-Prozesses die NSNotification ein, die ich im vorherigen Schritt erstellt habe.

Das Problem

Eingefügte Objekte werden in die Feineinstellung für den verwalteten Objektkontext des UI fehlerhaft und in der Benutzeroberfläche angezeigt. Das Problem kommt mit aktualisierten Objekten. Sie aktualisieren nur nicht.

Was ich versucht habe

  1. Die offensichtlichste Sache zu versuchen wäre um die sichere Benachrichtigung zu übergeben vom Helper App Prozess zum UI-Prozess. Einfach richtig? Nun, nein. Verteilte Benachrichtigungen werden nicht erlaube mir das als userInfo zu tun Wörterbuch ist nicht richtig Format. Deshalb mache ich all das NSArchivierungskram.

  2. Ich habe versucht, anzurufen refreshObject: mergeChanges: Ja ein die NSManagedObjects, die aktualisiert werden sollen, aber das scheint das nicht zu haben Wirkung.

  3. Ich habe versucht, die mergeChangesFromContextDidSaveNotification: Selektor auf dem Hauptfaden und der aktueller Thread Weder scheint das zu sein beeinflussen das Ergebnis.

  4. Ich habe es versucht mergeChangesFromContextDidSaveNotification: vorher zwischen Threads, welche von Natürlich ist es viel einfacher und es hat funktioniert perfekt. Aber ich brauche das Gleiche Funktionalität zwischen Prozessen.

Alternativen?

Fehle ich hier etwas? Ich habe ständig das Gefühl, dass ich das viel komplexer mache, als es sein muss, aber nachdem ich die Dokumentation mehrmals gelesen und ein paar solide Tage damit verbracht habe, sehe ich keinen anderen Weg, den MOC zu erneuern die Benutzeroberfläche.

Gibt es eine elegantere Art, dies zu tun? Oder mache ich irgendwo in meinem Code einen dummen Fehler?

Der Code

Ich habe versucht, es so leserlich wie möglich zu machen, aber es ist immer noch ein Durcheinander. Entschuldigung.

Helfer-App-Code

%Vor%

UI-Code

%Vor%     
John Gallagher 29.11.2009, 13:17
quelle

6 Antworten

1

Sie suchen nach - (void) refreshObject: (NSManagedObject *) Objekt mergeChanges: (BOOL) Flag glaube ich.

Dadurch wird das Objekt mit den Informationen im persistenten Speicher aktualisiert, wobei Änderungen bei Bedarf zusammengeführt werden.

    
Ben Lachman 10.12.2009, 19:13
quelle
2

Ich habe die Methode in

verwendet

Ссылка

dann ist jedes Objekt korrekt fehlerhaft, aber die Fehler werden im Cache abgerufen, also noch kein Update

Ich musste tun [moc stalenessInterval = 0];

Und es hat endlich funktioniert, mit Beziehung.

    
Wid 28.01.2011 16:31
quelle
1

Ich würde mit Mikes Vorschlag gehen und einfach die Filialdatei nach Änderungen beobachten.

Obwohl es möglicherweise nicht die effizienteste Lösung ist, habe ich - [NSManagedObjectContext reset] erfolgreich aus einem zweiten Prozess verwendet, wenn ein Store geändert wurde. In meinem Fall ist der Code ziemlich linear - alles was ich tue ist eine Fetch-Anfrage für einige Daten nach dem Zurücksetzen auszuführen. Ich weiß nicht, wie dies mit Bindings und einer komplizierten Benutzeroberfläche funktioniert, aber Sie können möglicherweise eine Benachrichtigung posten, um Dinge manuell zu aktualisieren, wenn dies nicht automatisch geschieht.

    
wbyoung 13.12.2009 15:38
quelle
1

Ich hatte genau dieses Problem mit einer iPhone App, an der ich gearbeitet habe. In meinem Fall beinhaltete die Lösung das Setzen von stalenessInterval des Kontexts auf etwas geeignet infinitesimales (z. B. 0,5 Sekunden).

    
nzeltzer 10.03.2010 03:13
quelle
1

Dies funktioniert, außer für Sandbox-Apps. Sie können keine Benachrichtigung mit einem Benutzer-Info-Diktat senden. Betrachten Sie stattdessen einen anderen IPC wie XPC oder DO.

Nebenbei bemerkt ist die Verwendung von NSDustributedNotificationCenter nicht immer 100%, wenn das System beschäftigt ist.

    
Arvin 06.12.2011 21:29
quelle
0

Das Festlegen von stalenessInterval des verwalteten Objektkontexts funktioniert. Mein Fall beinhaltet mehrere Threads anstelle von Prozess.

    
billibala 02.09.2010 16:21
quelle

Tags und Links