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.
confinementConcurrencyType(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.
privateQueueConcurrencyType: 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.
mainQueueConcurrencyType: 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.