Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using -com.apple.CoreData.ConcurrencyDebug 1 on async block crash on both MainContext and PrivateContext

I've added -com.apple.CoreData.ConcurrencyDebug 1 flag to my target. The problem is that I have a background block that is running, and crashes when I'm using either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType

My Code:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
 [privateManagedObjectContext setParentContext:_mainContext];
 [User fetchUserWithContext:_ privateManagedObjectContext];
}];

I've also tried:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 [User fetchUserWithContext:_mainContext];
}];

In both situations I get:

CoreData`+[NSManagedObjectContext Multithreading_Violation_AllThatIsLeftToUsIsHonor]:

Thanks for your help,

like image 366
Lasti Avatar asked Mar 22 '15 20:03

Lasti


1 Answers

That's not how Core Data queue concurrency works. When using either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType, you need to use the performBlock or performBlockAndWait methods on NSManagedObjectContext whenever you access the context. The fact that you're using GCD here is irrelevant; if you're using queue concurrency, you must use those methods, or you're doing it wrong.

You need to put your fetchUserWithContext call inside a block passed to one of those methods. You also need to put anything else that accesses objects fetched from the context inside a block passed to one of those methods.

like image 86
Tom Harrington Avatar answered Sep 27 '22 22:09

Tom Harrington