5

Ho due istanze di NSManagedObjectContext: una è utilizzata nella filettatura principale e l'altra è utilizzata in una sottofilettatura (tramite NSOperation). Per la sicurezza dei thread, questi due contesti condividono solo uno NSPersistentStoreCoordinator.Copia di modifiche in sospeso tra NSManagedObjectContexts con archivio persistente condiviso?

Il problema riscontrato è che le modifiche in sospeso nel primo contesto (sul thread principale) non sono disponibili per il secondo contesto fino a quando non viene eseguito un -save. Ciò è comprensibile poiché l'archivio persistente condiviso non avrà copie dello NSManagedObjects tracciato da -insertedObjects, -updatedObjects e -deletedObjects sono persistenti.

Sfortunatamente, questo presenta un problema con l'esperienza dell'utente: eventuali modifiche non salvate non verranno visualizzate nei rapporti (che richiedono molto tempo) generati nel thread in background.

L'unica soluzione che riesco a pensare è cattiva: prendere gli oggetti inseriti, aggiornati e cancellati dal primo contesto e inserirli nel grafico dell'oggetto del secondo contesto. Ci sono alcune relazioni piuttosto complesse nel set di dati, quindi sono riluttante ad andare in questa direzione. Spero che qualcuno qui sia una soluzione migliore.

risposta

4

Se questo è inferiore a 10.7 ci sono alcune soluzioni: una è che puoi avere nidificato ManagedObjectContexts, quindi puoi "salvare" in quello che si sta modificando e non salverà fino al disco, ma renderà le modifiche disponibili per altri bambini del contesto principale.

Prima del 10.7, probabilmente dovrai copiare le modifiche su te stesso. Questo non è super-duro dal momento che puoi semplicemente ascoltare un singolo oggetto per e quindi applicare nuovamente le modifiche esattamente dal contesto principale. (Dovrebbero essere circa 20 righe di codice.) Non devi mai salvare questo secondo contesto presumo?

+0

Grazie Wil! Mi piacerebbe scegliere come target 10.6, anche se è sempre più difficile ogni giorno :-) - Sto già monitorando la notifica di modifica, ma non sono sicuro di come si applicano nuovamente le modifiche e si mantengono le relazioni tra entità. potresti essere un po 'più specifico? – chockenberry

+0

Ah si. Stavo facendo in modo invisibile un'ipotesi basata sul mio modello, ovvero che ogni oggetto ha una chiave UUID (stringa) mantenuta dall'utente. –

+0

Senza il salvataggio sullo sfondo MOC gli inserti non saranno visibili al MOC principale (senza MOC annidati). Gli aggiornamenti/eliminazioni per gli oggetti esistenti dovrebbero funzionare se si ascolta la notifica di modifica (rilasciata dopo processPendingChanges) e si aggiornano da soli gli oggetti. – diederikh

2

Non sono sicuro se si dispone di restrizioni del sistema operativo, ma in iOS 5/Mac OS 10.7 è possibile utilizzare contesti oggetto nidificati gestiti per ottenere ciò. Credo che un contesto figlio sia in grado di inserire modifiche non salvate nel genitore semplicemente facendo un nuovo recupero.

Edit: Sembra Wil me battuto sul tempo, ma sì, prima di iOS 5/Mac OS 10.7 dovrete ascoltare il NSManagedObjectContextDidSaveNotification e dare un'occhiata al dizionario userInfo per l'aggiunta/aggiornamento/cancellato oggetti.

0

Una soluzione alternativa potrebbe implicare l'utilizzo di un singolo contesto di oggetti gestiti e fornire la sicurezza del proprio thread sull'accesso ad esso, oppure utilizzare i metodi di blocco e sblocco del contesto.

0

Vorrei provare a fare il thread principale per un normale salvataggio in modo che il secondo contesto possa semplicemente unire le modifiche nel suo contesto. "combattere" per un utilizzo delle API non è mai una buona idea. È possibile contrassegnare il record appena salvato con un attributo come intermedio ed eliminarlo in seguito se l'utente annulla definitivamente la modifica.

soluzione di questi problemi con attributi nei tuoi entità e l'interrogazione in thread in background con un corrispondente predica sarebbe stato facile ...

E sarebbe una soluzione stabile pure. Vengo da un mondo basato su database (oracle), spesso utilizziamo tali pattern (attributi di stato nei record) per rendere i dati visibili/invisibili ad altre sessioni DB (che sarebbero uguali ai thread in un'app di cacao). Funziona sempre senza problemi. Gli altri thread/sessioni visualizzano sempre solo i cambiamenti commessi, ovvero il modo in cui la maggior parte degli RDBMS funziona.