I am working on a cocoa software and in order to keep the GUI responsive during a massive data import (Core Data) I need to run the import outside the main thread.
Is it safe to access those objects even if I created them in the main thread without using locks if I don’t explicitly access those objects while the thread is running.
With Core Data, you should have a separate managed object context to use for your import thread, connected to the same coordinator and persistent store. You cannot simply throw objects created in a context used by the main thread into another thread and expect them to work. Furthermore, you cannot do your own locking for this; you must at minimum lock the managed object context the objects are in, as appropriate. But if those objects are bound to by your views a controls, there are no ‘hooks’ that you can add that locking of the context to.
There’s no free lunch.
Ben Trumbull explains some of the reasons why you need to use a separate context, and why ‘just reading’ isn’t as simple or as safe as you might think, in this great post from late 2004 on the webobjects-dev list. (The whole thread is great.) He’s discussing the Enterprise Objects Framework and WebObjects, but his advice is fully applicable to Core Data as well. Just replace ‘EC’ with ‘NSManagedObjectContext’ and ‘EOF’ with ‘Core Data’ in the meat of his message.
The solution to the problem of sharing data between threads in Core Data, like the Enterprise Objects Framework before it, is ‘don’t.’ If you’ve thought about it further and you really, honestly do have to share data between threads, then the solution is to keep independent object graphs in thread-isolated contexts, and use the information in the save notification from one context to tell the other context what to re-fetch.
-[NSManagedObjectContext refreshObject:mergeChanges:]is specifically designed to support this use.