Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreData: update in background and reading in main thread causes dead lock

I'm displaying a table with some data to the user. As soon as the view is presented, I'm making a web call to see if there's updated data (asynchronously). When the service call returns, I'd like to update my core data and the view.

Unfortunately I'm often getting dead locks because the view reads the same data as the service call writes. How can I solve this?

When I pause the simulator as soon as it's frozen, the waiting threads are waiting at the following places:

Background (updating) thread: (psynch_cvwait)

[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];

Main thread: (psynch_mutexwait) performing a filteredArrayUsingPredicate

Thanks a lot!

like image 577
swalkner Avatar asked Nov 22 '11 11:11

swalkner


2 Answers

-mergeChangesFromContextDidSaveNotification: will block the main thread. That call will lock both NSManagedObjectContext instances while it updates the main context with the changes being passed in.

This is generally considered unavoidable in pre-iOS 5 applications. You can minimize it by making more frequent, smaller, saves but it is still going to happen.

The only other option for pre-iOS 5 applications is to tell the main context to -reset: but that will require re-fetching everything -- another delay.

like image 142
Marcus S. Zarra Avatar answered Sep 28 '22 01:09

Marcus S. Zarra


It looks like the main thread is trying to grab some low level lock that the background thread already has (or vice versa). Are you using @synchronized somewhere to provide mutex?

Anyway, is there any reason why your background thread needs to wait for -mergeChangesFromContextDidSaveNotification: to complete? If not, pass NO as the last parameter.

like image 23
JeremyP Avatar answered Sep 28 '22 03:09

JeremyP