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
Post a Comment