Ios 有没有办法确定NSManagedObjectContext在哪个线程上?
我对NSManagedObjectContext线程的理解是,它只能在创建它的线程上执行核心数据获取请求、删除等。是否有任何方法可以检查在哪个线程上创建了一个Ios 有没有办法确定NSManagedObjectContext在哪个线程上?,ios,objective-c,multithreading,core-data,thread-safety,Ios,Objective C,Multithreading,Core Data,Thread Safety,我对NSManagedObjectContext线程的理解是,它只能在创建它的线程上执行核心数据获取请求、删除等。是否有任何方法可以检查在哪个线程上创建了一个NSManagedObjectContext,或者在特定的执行点,当前线程是否是特定NSManagedObjectContext的线程 谢谢 据我所知,你不能。至少不太容易。为什么?使用-performBlock:-它将在正确的线程上执行所有请求 我对NSManagedObjectContext线程的理解是,它只能在创建它的线程上执行核心数
NSManagedObjectContext
,或者在特定的执行点,当前线程是否是特定NSManagedObjectContext
的线程
谢谢 据我所知,你不能。至少不太容易。为什么?使用
-performBlock:
-它将在正确的线程上执行所有请求
我对NSManagedObjectContext线程的理解是,它只能在创建它的线程上执行核心数据获取请求、删除等
这不太准确。最好说上下文不能由多个线程或队列同时使用。处理此问题的常用方法是为每个线程/队列创建不同的上下文。还可以使用performBlock
和performBlock和wait
方法在多个线程上使用上下文,同时保持有效的单线程上下文访问
因此,上下文没有属于线程或队列的任何概念,线程也没有对在其上创建的上下文的任何引用
如果采用每个线程或队列一个上下文的方法,则需要跟踪代码将在何处运行并使用适当的上下文。例如,在使用GCD时,为特定的调度队列创建一个上下文,并且仅当您使用类似于dispatch\u async
的东西在该队列上运行时才使用它
如果确实要将上下文与队列链接,可以使用自己的数据结构从正在使用的任何并发方案中查找上下文——通过当前的
NSOperationQueue
,或dispatch queue,或NSThread
,或其他方式。这是很少需要的,但如果你找不到更好的技术,这是可能的。对不起,汤姆·哈林顿,但事实上这根本不正确。虽然从技术上讲,您可以这样做,但结果将是随机的,并且通常(根据我的经验)会导致非常难以调试的竞争条件
文档明确指出您应该为每个线程使用上下文。事实上,甚至一些最好的框架(如MagicalRecord)也是这样运行的。NSManagedObject及其上下文不是线程安全的,但是ObjectID是线程安全的
要检查更改,您可以将更改保留到父上下文,也可以侦听提供的通知。使用第二种方法,您需要读取要访问的项的objectid,然后从本地上下文再次请求它们
阅读以下Apple文档以更好地了解其工作原理
经过进一步研究,我发现一个文档最近在过去几周内更新过,尽管您在performBlock方法方面是正确的,但它仍然声明您不应该在线程之间传递上下文。也许我看错了问题,回答得有点快。我最近一直在开发一个基于CoreData的大型应用程序,我知道我们遇到了很多与上下文和线程相关的问题,所以我反应有点快。;)
我其实不需要实现这一点,我只是好奇而已。谢谢你这么彻底的回答!我不确定你说的话和汤姆的帖子有什么关系。此外,您的声明
文档明确指出您应该为每个线程使用上下文是不准确的。充其量,您指的是与约束模式相关的部分过时文档。Apple最近直接提供的大多数文档和建议都建议忽略所有线程,并使用performBlock
与托管对象上下文进行交互。确实,您应该使用新的并发初始化器和performBlock。然而,这些新的API只能解决与跨上下文合并相关的问题。它们不会突然生成上下文,甚至不会使NSManagedObject的线程安全。因此,重要的是每个线程只使用1个上下文,然后按照您的建议,使用performBlock保存更改。也许我误解了您的观点。新的API确实使使用MOCs线程安全。。。与使用任何同步API使使用对象成为线程安全的方式相同。如果您使用限制API,您需要关心您在哪个线程上。否则,您应该完全忘记线程,将每个访问都封装在一个performBlock
方法中,因为这是核心数据提供的同步APIperformBlock
不仅仅用于保存和合并。确切地说。。老实说,我想我已经忘了我的观点哈哈。。但是,是的,这正是我想说的,以确保所有访问都在performBlock内完成,否则可能会导致胎面安全问题。;)