2013-05-20 14 views
6

Gli oggetti NSManagedObjectContext hanno ottenuto performBlock: ed eseguonoBlockAndWait: metodi aggiunti per semplificare la concorrenza. Li ho usati - potenzialmente abbastanza ingenuamente - e mi sono appena reso conto che c'è una domanda che non ho mai fatto.È possibile utilizzare un oggetto NSManagedObject al di fuori del suo performBlock del contesto?

Se creo una sottoclasse NSManagedObject all'interno di uno dei metodi performBlock, il thread 'home' è il thread del suo contesto padre - che nel caso di NSPrivateQueueConcurrencyType è probabilmente un thread indipendente a cui non ho altri accessi.

Quindi è necessario effettuare una chiamata PerformBlock solo per accedere ai dati contenuti nei miei oggetti gestiti? O c'è una magia di sottofondo in grado di aiutarmi a proteggermi in caso di utilizzo di getter? (O setter, anche se sembra una cattiva idea ...)

risposta

13

NSManagedObject non deve essere utilizzato al di fuori della sua thread/coda managedObjectContext s (a volte funziona e alcune volte si blocca ==> non fare esso).

CoreData non garantisce l'accesso in lettura sicuro all'oggetto.

Per accedere a un oggetto di proprietà di un contesto "coda privata", utilizzare sempre o [context performBlock:...] o [context performBlockAndWait:...], a meno che non si accede sue objectID o managedObjectContext proprietà.

+0

Grazie, praticamente quello che stavo pensando era necessario ... Speravo di aver sbagliato. Ho bisogno di rivedere il video del WWDC in cui hanno introdotto la tecnica, perché non ricordo che debbano farlo ... Poi, di nuovo, sospetto che ci siano molti video WWDC che devo rivedere. – RonLugge

+1

Vorrei solo aggiungere che i tecnici Apple affermano esplicitamente che le letture su "NSManagedObject" non sono thread-safe perché i dati di base fanno il caching e le scritture cache non sono thread safe –

9

È necessario utilizzare performBlock: o performBlockAndWait:, ma c'è un'eccezione. Se si utilizza NSMainQueueConcurrencyTypee si sta utilizzando l'oggetto gestito nella coda principale, è possibile accedervi direttamente, senza blocco. Questo può essere di grande utilità quando è necessario aggiornare l'interfaccia utente da un oggetto gestito o viceversa.

+1

Un'altra eccezione è 'NSConfinementConcurrencyType' che è simile alla coda principale , solo per un thread specifico (la "vecchia" versione dei contesti gestiti) –

+0

Suppongo che avrei dovuto formulare meglio la mia domanda, poiché essenzialmente SOLO riguarda i tipi NSPrivateQueue e NSMainQueue ... anche allora, principalmente alla versione di coda privata grazie a questa meravigliosa eccezione. – RonLugge

Problemi correlati