2009-09-21 1 views
14

Nella documentazione di base dei dati di Apple per Concurrency with Core Data, viene elencato il metodo preferito per la sicurezza dei thread utilizzando un NSManagedObjectContext separato per thread, con un NSPersistentStoreCoordinator condiviso.Uso multithread dei dati principali (NSOperationQueue e NSManagedObjectContext)

Se ho un numero di NSOperazioni in esecuzione uno dopo l'altro su un NSOperationQueue, ci sarà un grande sovraccarico che crea il contesto con ogni attività?

Con NSOperationQueue con un numero massimo di operazioni simultanee pari a 1, molte delle mie operazioni utilizzeranno lo stesso thread. Posso usare il dizionario dei thread per creare un NSManagedObjectContext per thread? Se lo faccio, avrò problemi a ripulire i miei contesti più tardi?

Qual è il modo corretto di utilizzare i dati di base in questa istanza?

risposta

19

Il modo corretto di utilizzare Core Data in questo caso è quello di creare un separato NSManagedObjectContext per ogni operazione o di avere un unico contesto che si blocca (via -[NSManagedObjectContext lock] prima dell'uso e -[NSManagedObjectContext unlock] dopo l'uso). L'approccio bloccato potrebbe avere senso se le operazioni sono di tipo seriale e non ci sono altri thread che usano il contesto.

Quale approccio da utilizzare è una domanda empirica che non può essere interrotta senza dati. Ci sono troppe variabili per avere una regola generale. Numeri difficili da test delle prestazioni sono l'unico modo per prendere una decisione informata.

+1

FYI - 'lock' e' unlock' sono deprecati in iOS8 e OSX 10.10. La raccomandazione è: "Usa un contesto stile coda e -performBlockAndWait: invece" –

2

Le operazioni avviate utilizzando NSOperationQueue utilizzando un numero di operazioni simultanee massimo pari a 1 non eseguiranno tutte le operazioni sullo stesso thread. Le operazioni verranno eseguite una dopo l'altra, ma ogni volta verrà creato un nuovo thread.

Quindi la creazione di oggetti nel dizionario dei thread sarà di scarsa utilità.

+2

Non è garantito che sarà sempre un nuovo thread. Infatti, su Snow Leopard, NSOperationQueue utilizza Grand Central Dispatch che riutilizza esplicitamente i thread. –

+0

Questa domanda riguarda iPhone e non Snow Leopard. E ovviamente non c'è ** garanzia **, c'è mai? –

2

Mentre questa domanda è obsoleta, in realtà è in cima ai risultati di ricerca di Google su "NSMangedObjectContext threading", quindi mi limiterò a inserire una nuova risposta.

Il nuovo metodo "preferito" consiste nell'utilizzare initWithConcurrencyType: e indicare al MOC se si tratta di un thread principale MOC o di un thread secondario. È quindi possibile utilizzare il nuovo performBlock: ed eseguireBlockAndWait: metodi su di esso e il MOC si prenderà cura delle operazioni di serializzazione sul suo thread 'nativo'.

Il problema diventa quindi come gestire in modo intelligente la fusione dei dati tra i vari MOC che l'applicazione può generare, insieme ad altri mille dettagli che rendono la vita 'divertente' come programmatore.