Is there a way to figure out what thread an NSManagedObjectContext is on?

只谈情不闲聊 提交于 2020-01-24 10:35:07

问题


My understanding of threads with respect to an NSManagedObjectContext is that it can only execute core data fetch requests, deletes, etc., on the thread from which it was created. Is there any way to check to see what thread an NSManagedObjectContext was created on, or if at a particular point of execution the current thread is that of a particular NSManagedObjectContext?

Thanks!


回答1:


My understanding of threads with respect to an NSManagedObjectContext is that it can only execute core data fetch requests, deletes, etc., on the thread from which it was created.

That's not really accurate. It would be better to say that contexts cannot be used concurrently by more than one thread or queue. A common approach to dealing with this is to create different contexts for each thread/queue. It's also possible to use the performBlock and performBlockAndWait methods to use contexts on multiple threads while keeping context access effectively single-threaded.

As a result, contexts don't have any notion of belonging to a thread or queue, nor do threads have any reference to contexts that were created on them.

If you follow the approach of one context per thread or queue, you need to keep track of where code will run and use the appropriate context. For example when using GCD, create a context for a specific dispatch queue, and only use it when you've used something like dispatch_async to run on that queue.

If you really want to link a context with a queue, you could use your own data structure to look up contexts from whatever concurrency scheme you're using-- by the current NSOperationQueue, or dispatch queue, or NSThread, or whatever. This is rarely needed, but it's a possibility if you can't find better techniques.




回答2:


As far as I know you can't. At least not too easily. Why? Use -performBlock: - it will perform all requests on the correct thread.




回答3:


Sorry Tom Harrington, but that's actually not at all correct. Although you can technically do this, the results will be random and usually (in my experience) result in race conditions that become extremely difficult to debug.

The DOCs explicitly indicate that you should use a context PER thread. In fact even some of the best frameworks around (i.e. MagicalRecord) behave in this way. NSManagedObject's and their contexts are NOT thread safe, however objectIDs are.

To check for changes, you could either persist your changes up to the parent context's or you can listen to the notifications provided. Using the second method, you'll then need read the objectIDs of the item(s) you want to access, then request them again from your local context.

Read the following Apple Documentation to better understand how this works.

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/coredata/Articles/cdConcurrency.html


After further research I have found a document last updated over the past few weeks and although you are correct in regards to the performBlock methods it does still state that you should not pass contexts between threads. Perhaps I misread the question and responded a little quickly. I've recently been working on a large CoreData based application and I know we have had a lot of issues related to contexts and threads, so I responded a little quick. ;)

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html



来源:https://stackoverflow.com/questions/18413003/is-there-a-way-to-figure-out-what-thread-an-nsmanagedobjectcontext-is-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!