8

I want to use an NSOperationQueue to dispatch CoreData operations. However, operation queue behavior is not always the same (e.g. it dispatches using libdispatch on iOS 4.0/OS 10.6 which uses thread pools) and a queue might not always use the same thread (as NSManagedObjectContext requires).

Can I force a serial NSOperationQueue to execute on a single thread? Or do I have to create my own simple queuing mechanism for that?

  • You might not need to know on which thread your operation is executing. You can just lock the context (with `- [context lock]`) and unlock it once you are done. Beware not accessing any Core Data property out of the locked block. Do not forget to set the maximum concurrent operation to 1 to avoid the need for context synchronization. – cdelacroix Jul 14 '12 at 23:24

2 Answers2

4

Can I force a serial NSOperationQueue to execute on a single thread? Or do I have to create my own simple queuing mechanism for that?

You shouldn't need to do either of those. What Core Data really requires is that you don't have two pieces of code making changes to a managed object context at the same time. There's even a note on this at the very beginning of Concurrency with Core Data:

Note: You can use threads, serial operation queues, or dispatch queues for concurrency. For the sake of conciseness, this article uses “thread” throughout to refer to any of these.

What's really required is that you serialize operations on a given context. That happens naturally if you use a single thread, but NSOperationQueue also serializes its operations if you set maxConcurrentOperationCount to 1, so you don't have to worry about ensuring that all operations take place on the same thread.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • 4
    Warning: this answer is 'wrong'! Coredata needs one context per THREAD (real ones!) – Daij-Djan Nov 02 '12 at 08:48
  • @Dominick, please provide an authoritative reference for your assertion. The info in my answer comes straight from Apples docs, and the same idea has been repeated at WWDC a number of times. – Caleb Nov 02 '12 at 12:19
  • @Cocoaster If MOCs had to be tied to a specific thread it'd be difficult to use Core Data in blocks since you don't have control over which GCD worker thread runs a given block. – Caleb Nov 02 '12 at 12:21
  • 1. write my name right @caleb :P also the docs linked in your post contradict. and from google. e.g. : http://stackoverflow.com/questions/67154/is-it-safe-to-manipulate-objects-that-i-created-outside-my-thread-if-i-dont-exp – Daij-Djan Nov 07 '12 at 13:31
  • @Dominik The documentation agrees with me. In fact, the "note" above *is* a direct quote from the linked document. Please read the first section of the linked document carefully -- it says exactly what I say above. You can use threads, operation queues, or dispatch queues to ensure that access to a MOC is serialized. If you see a disagreement between what I wrote and what the document says, please point it out specifically. Also, I'm quite sorry about the misspelling -- I hate when people do that! ;-) – Caleb Nov 07 '12 at 15:41
  • @Dominik The question you refer to asks specifically about using a MOC with threads, so it's no surprise that the answer talks only about threads. That doesn't mean that threads are the only acceptable concurrency mechanism for use with Core Data. See [What does Apple mean when they say that a NSManagedObjectContext is owned by the thread or queue that created it?](http://stackoverflow.com/q/4800889/643383) for an excellent discussion about all this. – Caleb Nov 07 '12 at 15:57
  • @caleb the last link you provide seems to conflict with your answer? It finishes: "So do not expose an NSManagedObjectContext* to more than one thread (actor, etc) under any circumstance.". My personal experience is that any kind of access - READS as well as writes - breaks CD in very strange ways. – Adam Jun 24 '13 at 10:58
  • @Adam Then you've misunderstood my answer or the linked answer. Please read the linked answer carefully (the whole thing), and also the note from the docs that I quoted above and the previous comments here. `NSOperationQueue` is a valid mechanism for serializing access to a MOC, and the use of "thread" in these contexts is simply shorthand for "thread/dispatch queue/operation queue". – Caleb Jun 24 '13 at 12:36
0

Apple decided to bind managed objects to real Threads.. it isnt that safe anymore to access a context on different threads - a context without any objects MIGHT be safe but its objects are not

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • Again, please provide a reference. Your advice here contradicts the Core Data documentation, and I don't see anything to support your answer in the iOS 6 SDK release notes. So where are you getting your information? – Caleb Nov 02 '12 at 13:45
  • see docs in your answer above ;) and see google.. e.g.: http://stackoverflow.com/questions/67154/is-it-safe-to-manipulate-objects-that-i-created-outside-my-thread-if-i-dont-exp – Daij-Djan Nov 07 '12 at 13:30
  • sigh .. why the down vote - please at least spend a few seconds to explain it – Daij-Djan Jun 30 '15 at 17:45