Nested executeBlock: in NSManagedObjectContext

When using the NSPrivateQueueConcurrencyType and NSMainQueueConcurrencyType for NSManagedObjectContext , is it safe to make nested executeBlock calls in the same context?

 [backgroundContext performBlock:^{ NSFetchRequest *myRequest = ...; __block NSArray *result= nil; [backgroundContext performBlockAndWait:^{ results = [backgroundContext executeFetchRequest:myRequest error:NULL]; }]; }]; 

This may sound silly, but I have an existing code base with lots of helper methods that encapsulate executeFetchRequest calls. I do not want to make assumptions that the caller has already used executeBlock or not. For example:

 -(void)updateObjects:(BOOL)synchronous { if (YES == synchronous) [self fetchHelper]; else { [backgroundContext performBlock:^{ [self fetchHelper]; }]; } } -(NSArray*)fetchHelper { [self.backgroundContext performBlockAndWait:^{ //Fetch the objects... [self.backgroundContext executeFetchRequest: (...)]; }]; } 

I tried and it works. But I learned (the hard way) to be very careful with Core Data and multi-threaded.

+8
ios core-data nsmanagedobjectcontext
source share
1 answer

Yes, executeBlockAndWait is reentrant. Directly from Apple's notes ...

The master data formalizes the concurrency model for the NSManagedObjectContext class with the new parameters. When you create a context, you can specify the concurrency template that will be used with it: flow restriction, private dispatch queue, or main dispatch queue. The NSConfinementConcurrencyType parameter provides the same behavior that was present in iOS versions prior to 5.0 and is the default. When sending messages to the context created using the association queue, you should use executeBlock: or performBlockAndWait: if your code is not already running on this queue (for the main type of the queue) or within the executeBlock ... invocation action (for the type of the private queue) . Within the blocks passed by these methods, you are free to use the NSManagedObjectContext methods. executeBlockAndWait: method supports reimplementation of the API. Execution: The method includes a resource pool and calls the processPendingChanges method upon completion.

+8
source share

All Articles