0

There is topic about Thread Confinement pattern in Core Data programming Guide and it says that

You must create the managed context on the thread on which is will be used. If you use NSOperation, note that its init method is invoked on the same thread as the caller. You must not, therefore, create a managed object context for the queue in the queue’s init method, otherwise it is associated with the caller’s thread. Instead, you should create the context in main (for a serial queue) or start (for a concurrent queue).

I just can't get why is that? Where is the difference?

TylerH
  • 20,799
  • 66
  • 75
  • 101
folex
  • 5,122
  • 1
  • 28
  • 48

2 Answers2

2

It says why pretty clear in the documentation that you quoted. The operations init method runs on the callers thread while the work that happens in the main method may run on another thread.

Since you cannot share managed object contexts between threads you need to create it on the same thread as you will be using it. Thus, if you use it in the operation you need to make sure that the context is created on the same thread as the operation runs on.

The reason why serial operations create the context in main is that they run the default start implementation while you override start when you implement concurrent operations.

You can read more about how concurrent operations work in the Concurrency Programming Guide (tip: search for "start")

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • Oh, I've completely forgot that there is no need to reimplement `start` method in non-concurrent operations. Thanks a lot. – folex Jun 27 '12 at 12:01
0

David is right.

The documentation is saying that if, for example, you have a NSOperation subclass called MyOperation and you override the init method like the following

- (id)init
{
   if(self = [super init]) {

        // your context here       
   }

   return self;
}

Then, if you instantiate that operation in the main thread like

MyOperation* op = // alloc-init

the context you have created is linked with the main thread and NOT with the thread where the operation runs into.

Strange things could happen when you perform changes (deletion, update, etc) on managed objects since you are changing them on background but you access a context that is in the main thread.

Override main instead and create the context there:

- (void)main
{
    // your context here
}
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190