multithreading - iOS: Synchronizing access to CoreData -


i'm new coredata , i'm trying create simple application.

assume have function:

func saveentry(entry: entry) {    let moc = nsmanagedobjectcontext(concurrencytype: .nsprivatequeueconcurrencytype)    moc.parentcontext = savingcontext    moc.pefrormblockandwait {      // find if moc has entry     // if not => create     // else => update     // saving logic here   } } 

it can introduce problem: if call saveentry 2 threads, passing same entry duplicate it. i've added serial queue db adapter , doing in following manner:

func saveentry(entry: entry) {     dispatch_sync(serialdbqueue) { // (1)         let moc = nsmanagedobjectcontext(concurrencytype: .nsprivatequeueconcurrencytype)         moc.parentcontext = savingcontext          moc.pefrormblockandwait {  // (2)             // find if moc has entry             // if not => create             // else => update             // saving logic here         }     } } 

and works fine, until i'd add interface function:

func saveentries(entries: [entry]) {     dispatch_sync(serialdbqueue) {  // (3)         let moc = nsmanagedobjectcontext(concurrencytype: .nsprivatequeueconcurrencytype)         moc.parentcontext = savingcontext          moc.pefrormblockandwait {              entries.foreach { saveentry($0) }         }     } } 

and have deadlock: 1 called on serialdbqueue , wait till saving finishes. 2 called on private queue , wait 3. , 3 waiting 1.

so correct way handle synchronizing access? far understand it's not safe keep 1 moc , perform saves on because of reasons described here: http://saulmora.com/coredata/magicalrecord/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord.html

i try implement single nsmanagedobjectcontext control mechanism. each context maintains serial operation queue multiple threads can call performblock: or performblockandwait: without danger of concurrent access (though must cautious of context's data changing between time block enqueued , when executes). long work within context being done on correct queue (via performblock) there's no inherent danger in enqueuing work multiple threads.

there of course complications consider , can't offer real suggestions without knowing more app.

  • what object responsible creating context , how made available every object needs it?
  • with shared context becomes difficult know when work on context "finished" (it's operation queue empty) if represents meaningful state in app.
  • with shared context more difficult abandon changes should you want discard unsaved modifications in event of error (you'll need revert changes rather discard context without saving).

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -