Apple's recommended method for multithreading core data is to use a managed object context per thread, and to send changes from one context to another by saving the changed thread's context to a shared persistent store.
While I can imagine that being fine for, eg. an RSS reader, for some applications it seems far from ideal. In my case, I'm writing a music sequencer that records & plays data using a background thread. I need recorded data to be accessible t开发者_如何学Pythono the main thread during record/playback. Having to constantly save and load data while recording/playing would be bad enough, but worse, it'd seem to force the user to save whenever they record or play, which kinda screams 'terrible application'.
However, it seems that there might be a way of sidestepping this. If other threads don't need access to the core data entities themselves (just the data they contain), what's to stop me from running the managed object context in its own thread, and only allowing other threads indirect access, for example by binding UI objects to a property that calls performSelector:onThread:withObject:waitUntilDone:
on the managed object context's thread to get/set values?
It doesn't give some of the benefits of multithreading (i.e. scaling core data to multicore CPUs), but a lot of the time, we just want multithreading to avoid locking up the UI while something intensive is happening.
I've not seen this pattern advocated for core data. Given that it can be a strange and unpredictable beast when you don't do exactly what apple suggests, I thought it'd be worth asking if this really does avoid the reasons we're discouraged from letting multiple threads access a single managed object context.
You have no control over the implementation details of an NSManagedObject's internals and, quite specifically, there are reasons why CoreData may need to do something in the context when you read an attribute.
For your particular needs, I would suggest a highly optimized isolated, buffer and queue, based solution where you copy what is need out of the CD objects before passing them to a background processing thread.
You can use performSelector:on*Thread: if you want, but then you'll be dealing with synchronization issues, latency, and other fun bits of concurrency. Personally, I would go with the queueing mechanism described above.
精彩评论