3
votes

I was exploring GCD with core data. I know that managed object context is not thread safe.

I created private context with option "NSPrivateQueueConcurrencyType". As per document I have to use performBlock or performBlockAndWait to do any operation with context, it will do that operation in its own private thread. My questions are,

  1. What are the operation I have to do inside perform block? Is it only accessing the context object or using managed object as well?
  2. Even if I insert a new object to database within "DispatchQueue.global().async"(without using perform block), it works fine. Why? (It is a different thread)
  3. Is that ok doing database operation in different thread, if we create context with "NSPrivateQueueConcurrencyType"?

I can use perform block for every database operation, but our project already has lots of code which are running in private queue. Please help me to understand this better.

1

1 Answers

2
votes

This answer is conclusion of answer given by Sandeep Bhandari. Here I assume everyone is clear with Thread and Queue concepts.

Always managed object context should be accessed from single thread at any point of time, because it is not thread safe. If we are using context in multiple thread, we should make sure that it is serialised, so that no two threads are accessing same context at same time. If it does it will crash.

iOS 5 and later, Apple has provided 3 ways to create the context.

  1. confinement​Concurrency​Type(Deprecated in iOS 10): If you create context with this option, it is your duty to make sure that you are doing all database operation in a thread which created this context.

  2. private​Queue​Concurrency​Type: If we are using this option to create context, it will create its own internal queue to crate this context and to make sure that all database operation happens in same thread. It will use internal queue only if you perform all your task with this context inside performBlock or performBlockAndWait. If you are using any other queue to do any database operation with this context it will work, if no two thread is accessing at same time. If two threads are accessing it, this will crash. It is very hard to manage this, since that task execution happens at run time depending on resource availability. This type of issues cannot be reproduce that easily. So use those performBlock API to do any database operation with this context.

  3. main​Queue​Concurrency​Type: If you are using this option to create the context, it will create managed object context in main thread. You need to do any database operation with this context in main thread. You can use performBlock here as well to make sure all task happens in main thread. Even doing any operation with this context will work fine in other thread, if no two thread is accessing at same time.