有没有办法弄清楚NSManagedObjectContext是什么线程?

时间:2013-08-23 22:49:16

标签: ios objective-c multithreading core-data thread-safety

我对NSManagedObjectContext的线程的理解是它只能在创建它的线程上执行核心数据获取请求,删除等。有没有办法检查创建NSManagedObjectContext的线程是什么,或者在特定的执行点,当前线程是否是特定NSManagedObjectContext的线程?

谢谢!

3 个答案:

答案 0 :(得分:1)

据我所知你不能。至少不太容易。为什么?使用-performBlock: - 它将在正确的线程上执行所有请求。

答案 1 :(得分:1)

  

我对NSManagedObjectContext的线程的理解是,它只能在创建它的线程上执行核心数据获取请求,删除等。

这不是很准确。最好是说上下文不能由多个线程或队列同时使用。处理此问题的常用方法是为每个线程/队列创建不同的上下文。也可以使用performBlockperformBlockAndWait方法在多个线程上使用上下文,同时有效地保持上下文访问的单线程。

因此,上下文没有任何属于线程或队列的概念,线程也没有对它们上创建的上下文的任何引用。

如果您按照每个线程或队列使用一个上下文的方法,则需要跟踪代码的运行位置并使用适当的上下文。例如,在使用GCD时,为特定的调度队列创建一个上下文,只有在使用dispatch_async之类的东西在该队列上运行时才使用它。

如果您确实想要将上下文与队列链接,您可以使用自己的数据结构从您正在使用的任何并发方案中查找上下文 - 通过当前NSOperationQueue或调度队列,或者NSThread,或其他什么。这很少需要,但如果你找不到更好的技术,这是可能的。

答案 2 :(得分:1)

对不起Tom Harrington,但实际上并不正确。虽然你可以在技术上做到这一点,结果将是随机的,并且通常(根据我的经验)导致竞争条件变得非常难以调试。

DOC明确指出您应该使用上下文PER线程。事实上,甚至一些最好的框架(即MagicalRecord)也以这种方式运行。 NSManagedObject及其上下文不是线程安全的,但是objectID是。

要检查更改,您可以将更改保留到父上下文,也可以收听提供的通知。使用第二种方法,您需要读取要访问的项目的objectID,然后再从本地环境中再次请求它们。

阅读以下Apple文档,以便更好地了解其工作原理。

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


经过进一步研究后,我发现过去几周内最新更新的文档虽然你在performBlock方法方面是正确的,但它仍然表明你不应该在线程之间传递上下文。也许我误解了这个问题并迅速作出了回应。我最近一直在研究一个基于CoreData的大型应用程序,我知道我们遇到了很多与上下文和线程有关的问题,所以我回复得有点快。 ;)

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