Why do I get a CoreData multithreading violation when trying to access a property of a fetched object? Why do I get a CoreData multithreading violation when trying to access a property of a fetched object? multithreading multithreading

Why do I get a CoreData multithreading violation when trying to access a property of a fetched object?


Could you please also add the code where the context initialisation happens?

The error you get is related to accessing a managed object context from a thread/queue other than the one it was initialised on.

What usually happens is that the managed object context is initialised using the default/legacy "confinement type" concurrency type for which the

performBlock: 

and

performBlockAndWait:

methods won't actually do what they advertise they do i.e. make sure the context is accessed on the queue it was associated with upon initialisation.

If what I suggested above is what is actually happening you could (assuming everything else is in place) fix this by initialising your context like so:

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

or

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

Here's the docs on concurrency strategies:

When you create a managed object context using initWithConcurrencyType:, you have three options for its thread (queue) association

Confinement (NSConfinementConcurrencyType)

For backwards compatibility, this is the default. You promise that context will not be used by any thread other than the one on which you created it. In general, to make the behavior explicit you’re encouraged to use one of the other types instead.

You can only use this concurrency type if the managed object context’s parent store is a persistent store coordinator.

Private queue (NSPrivateQueueConcurrencyType)

The context creates and manages a private queue.

Main queue (NSMainQueueConcurrencyType)

The context is associated with the main queue, and as such is tied into the application’s event loop, but it is otherwise similar to a private queue-based context. You use this queue type for contexts linked to controllers and UI objects that are required to be used only on the main thread.

If you use contexts using the confinement pattern, you send the contexts messages directly; it’s up to you to ensure that you send the messages from the right queue.

You use contexts using the queue-based concurrency types in conjunction with performBlock: and performBlockAndWait:.

Apple Docs

As a side note, the error message you get is one of the last few "easter eggs" still standing inside Cocoa.


The problem does no longer occur when building for iOS 9.0.