3

In the documentation: NSManagedObjectContext Class Reference it states:

Setter methods on queue-based managed object contexts are thread-safe. You can invoke these methods directly on any thread.

Can someone give a code example of what exactly this means. Does it actually mean to read "Setter methods on queue-based managed OBJECTS are thread-safe"

Also, if I have a managed object stored as an iVar (not best practice), can I called it's managedObjectContext method and its and then call performBlock() on this safely from within any thread?

bandejapaisa
  • 26,576
  • 13
  • 94
  • 112
  • I recommend you to have a look to this post. http://stackoverflow.com/questions/30875917/core-data-concurrency-queue-style-moc-getters-thread-safety – agy Jul 15 '15 at 13:34
  • Great, that is just what I'm looking for. Thanks again. – bandejapaisa Jul 15 '15 at 16:53

2 Answers2

2

No, it means exactly what it says. You can call setter methods on a NSManagedObjectContext from any thread. eg: -[setParentContext:], -[setPersistentStoreCoordinator:].

You can call -[performBlock:]and -[performBlockAndWait:] from any thread as it will execute the passed block on the context's queue.

Stephen Groom
  • 3,887
  • 1
  • 15
  • 23
  • To add to this correct answer, yes you can call `self.myManagedObject.managedObjectContext.performBlock...` if you wanted to. That is also safe. You cannot call anything that will potentially alter the state of the `NSManagedObject` instance on any thread but the thread that the context was assigned to. – Marcus S. Zarra Jul 15 '15 at 15:15
  • Cool thanks. Got the info I needed from Marcus' other post. – bandejapaisa Jul 15 '15 at 16:54
0

-[performBlock:] and -[performBlockAndWait:] are used to your app avoid accessing a managed object context or managed object from the wrong dispatch queue.

Let's imagine I have set up the managed object context as a background context with PrivateQueueConcurrencyType and we run this code on the main thread:

NSManagedObject *mo = [NSEntityDescription insertNewObjectForEntityForName:@"Address" inManagedObjectContext:backgroundContext];
mo.street = "Rue la place"
[backgroundManagedObjectContext save:&error]

This piece of code violates Core Data’s concurrency model by calling -[insertNewObjectForEntityForName::] with the private queue context as an argument from the main thread.

So we should wrap all access to backgroundContext in a block passed to performBlock: or performBlockAndWait:, which executes the block on the context’s private dispatch queue:

[self.backgroundManagedObjectContext performBlockAndWait:^{
  NSManagedObject *mo = [NSEntityDescription insertNewObjectForEntityForName:@"Address" inManagedObjectContext:backgroundContext];
  mo.street = "Rue la place"
  [backgroundManagedObjectContext save:&error]
}];
agy
  • 2,804
  • 2
  • 15
  • 22
  • Excellent answer but doesn't answer the question on whether setters on the context are thread-safe or if setters on the managed objects are thread safe. – Marcus S. Zarra Jul 15 '15 at 15:16
  • Yes, you are right. I should add that setters are thread-safe as long as it is called from the thread that the context was assigned. That's why performblock should be used. – agy Jul 15 '15 at 15:22
  • Also, the setters on the *context* **are** thread safe. Calling `-setParentContext:` and `-setPersistentStoreCoordinator:` is perfectly safe from any thread. – Marcus S. Zarra Jul 15 '15 at 15:29
  • Thanks for the effort, but as Marcus points out too, it's not quite what I was asking. – bandejapaisa Jul 15 '15 at 16:52