4

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

谢谢!

4

3 回答 3

2

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

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

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

如果您遵循每个线程或队列一个上下文的方法,您需要跟踪代码将在哪里运行并使用适当的上下文。例如,在使用 GCD 时,为特定的调度队列创建一个上下文,并且仅当您使用类似dispatch_async在该队列上运行的东西时才使用它。

如果您真的想将上下文与队列链接,您可以使用自己的数据结构从您正在使用的任何并发方案中查找上下文 - 通过 currentNSOperationQueue或 dispatch queue 或NSThread,或其他任何方式。这很少需要,但如果您找不到更好的技术,这是可能的。

于 2013-08-23T23:05:21.100 回答
1

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

于 2013-08-23T23:05:01.300 回答
1

对不起汤姆哈灵顿,但这实际上是不正确的。尽管您在技术上可以这样做,但结果将是随机的,并且通常(根据我的经验)会导致竞争条件变得非常难以调试。

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

于 2014-03-01T14:57:15.087 回答