2013-02-22 14 views
6

Nella mia app ho UITableViewController che mostra la lista degli eventi. Questo controller utilizza ManagedObjectContext Say ParentContext. Ora se è selezionato un evento, viene mostrato un controller di visualizzazione dettagliato in cui gli utenti possono modificare i dettagli dell'evento. Così ho creato un contesto bambino dire,Dati principali Multi livello padre - Contesto figlio

ChildContext with type "NSPrivateQueueConcurrencyType"

ChildContext whose parent Context is "ParentContext".

Il mio codice è:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    childContext.parentContext = self.context ; 

Ora di nuovo ci sono alcuni campi e le relazioni che ha bisogno di un altro drill-down. Così ho creato un altro ChildContext per il nuovo controller della vista dire,

GrandChildContext with type "NSPrivateQueueConcurrencyType"

GrandChildContext whose parent context is "ChildContext"

questo processo va per un altro livello (livello 4 Totale dai genitori (tableView) per bambino)

self.context - Parent Context 
    | 
    | 
ChildContext 
    | 
    | 
GrandChildContext 
    | 
    | 
GrandGrandChildContext 

My Entity Assomiglia a questo

EntityA   -- (Edit View Controller - uses ChildContext) 
| 
|- Field1 
| 
|- Field2 
| 
|- RelationShip (1 to Many) - (Relationship Add/Edit View Controller - uses GrandChildContext) 
    | 
    |- Field1 
    | . 
    | . 
    |- Field3 
    | 
    |- Relationship (1 to Many) - (Relationship Add/Edit View Controller - uses GrandGrandChildContext) 
      | 
      |- Field1 
      | 
      |- Field2 

È questo il modo corretto di utilizzare il contesto padre-figlio? Perché ad un certo punto di tempo avrò come 1 NSMainQueueConcurrencyType MOC and 3 NSPrivateQueueConcurrencyType MOC.

Se non lo è? c'è qualche altro modo?

Troppi contesti figli influiscono sulle prestazioni delle app?

Inizialmente ho utilizzato Proprietà e NSArrays per gestire i dati immessi dall'utente e quando l'utente preme il pulsante Esegui, aggiornerò/creerò oggetti gestiti. Ma questo è un lavoro noioso che ha reso il mio controller di visualizzazione sporco. Così sono passato al contesto Parent-Child, che è molto facile da salvare/scartare gli aggiornamenti.

Grazie

risposta

4

Potrebbe essere stato un po 'esagerato con i contesti multipli di bambini, ma solo un po', e il tuo approccio generale è corretto. Un MOC (contesto dell'oggetto gestito) è un oggetto abbastanza leggero.

Mi piace il tuo approccio di avere un riferimento distinto, all'interno di ogni controller/scena di visualizzazione, al MOC che si applica a quella scena.

A volte è utile pensare a un MOC come a una sessione oa uno scratchpad. La corrispondenza non è tra i MOC e le Entità, ma piuttosto tra i MOC e le unità logiche di lavoro.

Se uno dei tuoi drill down segna l'inizio di alcune attività di modifica che l'utente potrebbe voler abbandonare/annullare, è un buon momento per estrarre un MOC secondario e passarlo alla nuova visualizzazione. Puoi, se necessario, eseguire il rollback: o anche solo abbandonare il MOC, mentre ti rilassi al punto di partenza.

D'altra parte, se si stesse scrivendo semplicemente un visualizzatore per informazioni statiche, utilizzare solo un MOC. In tal caso non è necessario o non si beneficia dell'utilizzo di più.

+3

In tutti i drill down ho un'attività di modifica. Sono appena riuscito a ridurre alcune operazioni di salvataggio/annullamento in alcuni dei drill down. Dopo aver lavorato con questo modello per un po 'di tempo, l'unico problema che ho riscontrato è che la relazione creata non è visibile nel figlio genitore. Questo accade solo in iOS 5, si tratta di un bug noto e l'ho risolto chiamando getPermanentIDs appena prima di salvare contesti figlio – krishnan

+0

Oh mio dio, + krishnan, ho strappato i capelli a metà prima di trovare questo commento e ho provato ad aggiungere una chiamata getPermanentIDs. –

-1

Forse c'è una piccola quantità di confusione circa il miglior caso d'uso per annidati contesti oggetto gestito. Per il tuo caso, consiglierei di utilizzare solo un singolo contesto.

Lo spostamento verso i dati di base da array ecc. È stata un'ottima idea. Ora libera la vera potenza e semplicità del grafico dell'oggetto. Cerca di mantenere le cose semplici.

Per eseguire il drill down, basta passare il contesto al controller di visualizzazione figlio. Il controller dei risultati recuperato dai controller di visualizzazione figlio può utilizzare lo stesso contesto del controller di visualizzazione padre. Numerosi esempi di codice Apple utilizzano esattamente questo modello.

L'unica volta che hai bisogno di contesti è se hai davvero bisogno di concorrenza. Questo non sembra essere il caso qui. La nuova interfaccia del controller di visualizzazione figlio viene visualizzata una volta che i dati sono stati recuperati. Se ciò richiede troppo tempo (ad esempio, poiché i dati provengono da un servizio Web) viene visualizzata una sorta di interfaccia "please wait" e viene visualizzata l'interfaccia completa al termine del recupero dei dati. Molto probabilmente questo non è il tuo scenario.

+5

Se si guarda [link] (https://developer.apple.com/videos/wwdc/2012/) wwdc sessione 2012 di best practice per i dati core video 214, viene illustrato come utilizzare il contesto padre e figlio per visualizzare i dettagli guarda il controller. Sto usando la stessa tecnica, in modo che se l'utente preme il pulsante salva potrei salvare il contesto figlio e tutte le modifiche del contesto figlio verranno inviate al contesto padre. E quando l'utente preme il pulsante di annullamento, basta semplicemente chiudere il controller della vista e tutte le modifiche andranno perse. Qui tutti i controller di visualizzazione di my child sono ispettori di dettaglio in cui utilizzare modifica i dati, quindi nessun controller di risultati recuperato. – krishnan

+0

È possibile ottenere lo stesso con un solo contesto usando '[contesto rollback];' invece di '[context save: nil];'. Il video WWDC è utile se il recupero per il controller della vista dettagli richiederebbe una quantità eccessiva di tempo. – Mundi

+0

penso che tu non capisca la mia domanda. Le mie domande sono simili a questo [uno] (http://stackoverflow.com/questions/10443754/undo-all-changes-made-in-the-child-view-controller). Ma nel mio caso ho un contesto infantile a più livelli. Con '[context rollback]' tutte le mie modifiche andranno perse. Ma invece voglio solo alcune modifiche da scartare. Caricherò presto un progetto di esempio. grazie – krishnan