2010-01-26 21 views
9

Ho un'applicazione iPhone basata su Core Data che deve salvare 1000 oggetti gestiti alla chiusura. Questo richiede 8+ secondi, tuttavia, il sistema operativo uccide l'app se non completa in ca. 6 secondi.Salvataggio in background con i dati principali?

Non voglio salvare gli oggetti in precedenza, perché l'utente deve attendere 8 secondi per visualizzare i risultati.

È possibile in qualche modo salvare gli oggetti in precedenza in un thread in background, pur avendo ancora accesso (in sola lettura) a NSManagedObjectContext nel thread principale per visualizzare i dati? O è in qualche modo possibile duplicare gli oggetti gestiti e passare i duplicati a un thread in background per il salvataggio?

Per chiarimenti, ecco cosa succede ora nell'applicazione: ho un thread in background che importa più di 1000 oggetti in circa 1 secondo. Se salvo durante l'importazione, ci vuole molto più di 1 secondo. Pertanto, per visualizzare questi elementi con un ritardo minimo, il contesto viene trasferito senza salvare il thread principale e l'utente ottiene i risultati il ​​più velocemente possibile.

Ora ho il problema di come salvare questi oggetti senza che l'utente debba attendere gli 8 secondi. Se salvi il thread in background prima di consegnarlo, l'utente deve attendere. Se salvi il thread in primo piano dopo la consegna, l'utente deve attendere. Le uniche due possibili approcci posso vedere in questo momento sono:

  1. In qualche modo avere dati fondamentali che fanno la sua sqlite accessi nei precedenti, pur mantenendo il filo conduttore reattiva
  2. Consegnando gli oggetti non salvati da un contesto ad un altro, e salvataggio nel thread di sfondo

Entrambi gli approcci sembrano impossibili (almeno secondo la documentazione di Core Data). Quindi non c'è altra soluzione che avere l'utente aspettare più a lungo (e magari visualizzare una bella clessidra rotante :-)?

saluti, Jochen

risposta

8

Sì, c'è un modo per salvare il contesto oggetto gestito dal thread in background, o, più precisamente, di solito è indicato come "l'importazione in thread in background, e mostrando nel thread principale ". In questo modo, gli oggetti gestiti vengono salvati pezzo per pezzo quando vengono importati, non tutti alla volta alla fine.

Ho appena scritto una risposta breve su una domanda simile qui allo SO, ma dovresti leggere questo Apple doc. Ci sono molte potenziali insidie, quindi leggi molto, molto attentamente. E poi leggi Apple's "Efficiently Importing Data". Anche questo è un must! E anche lo CoreData book di Marcus Zarra è utile.

Il multithreading di CoreData è un po 'complicato, ma è davvero redditizio. In bocca al lupo!

+3

concordato. Salvarli mentre si effettua l'importazione è molto più efficiente di un enorme salvataggio all'uscita. Ho anche fatto una bella panoramica su Mac Developer Network che spiega anche come fare il salvataggio in background. –

+1

Grazie per l'aiuto. Ho provato a salvare durante l'importazione, con il risultato che il tempo di importazione aumenta. È più veloce del salvataggio alla fine, ma non abbastanza veloce. Ho chiarito la domanda al riguardo e sono sicuro che il multi-threading dei Core Data è complicato ... – Jochen

+0

Il tuo 1. dovrebbe essere possibile. Basta creare un 'NSManagedObjectContext' per thread. E mentre importi in background, non creare tutte le oltre 1000 entità contemporaneamente e salvarle contemporaneamente. Invece, crea 10 entità nel contesto, salvale, passale al thread principale e ripeti questo processo.In ogni caso, l'utente non può vedere più di 1000 voci contemporaneamente, quindi puoi ingannare il tuo utente in modo che tutti i dati siano disponibili. – Yuji

Problemi correlati