具有私有并发类型的 NSManagedObjectContext 在主线程上执行块
Posted
技术标签:
【中文标题】具有私有并发类型的 NSManagedObjectContext 在主线程上执行块【英文标题】:NSManagedObjectContext with private concurrency type executes block on main thread 【发布时间】:2012-07-29 22:35:17 【问题描述】:在 ios5 中,我有一个使用 NSPrivateQueueConcurrencyType 创建的 NSManagedObjectContext,如下所示:
self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
moc.parentContext = rootContext;
这在主线程上执行,但如果我正确理解了文档,那也没关系,因为 MOC 有自己的队列,对吧?
现在,有时我会执行一个获取请求,如下所示:
[self.moc performBlockAndWait:^() // (1)
NSError* err = nil;
result = [self.moc executeFetchRequest:request error:&err];
NSLog(@"%@ %@", [NSThread currentThread], [NSThread isMainThread]?@"MAIN":@"");
];
调用 (1) 也在主线程上调用。但我希望块内的获取请求在私有 MOC 线程上执行。到目前为止正确吗?
但是,如果我检查块内的当前线程,它实际上是主线程! NSLog 打印:
<NSThread: 0x6b10780>name = (null), num = 1 MAIN
检查线程转储可以确认这一点。
不应在主线程上执行 fetch,因为这偶尔会导致与其他一些正在运行的代码发生死锁。那么我在这里做错了什么?
【问题讨论】:
【参考方案1】:好的,我仍然不完全确定这里的机制,即发布在上下文私有队列上的内容如何最终出现在主线程上。我怀疑它与同步执行块的 performBlockAndWait 有关。我重写了一些东西,所以现在一切都是异步完成的,并且块现在在其私有线程上执行。
感谢所有建议。
【讨论】:
重新阅读我上面的答案。没有私人 MOC 队列 - 你从未创建过它。 NSPrivateQueueConcurrencyType 标志只是告诉 Core Data 你想如何使用它——它不会为你创建队列。您在上面的代码中所做的一切都在主队列中。 我试图编辑上述错误信息,超时。我的更正:我的信息是 iOS 4 - 很抱歉造成混淆。无论如何,我认为正在发生的事情是 MOC 正在其队列上进行工作,并且为了方便您,将您发送回与您发送消息的同一线程上。因此,由于您要求它执行操作并等待它(performBlockAndWait),它在其线程上执行工作但阻塞主线程。您可以在此消息之前和之后记录并记录时间差以检验此假设。 感谢您的更正。我再次在文档中查找它,它明确指出在指定 NSPrivateQueueConcurrencyType 时“上下文创建并管理私有队列”。我怀疑你所描述的事情正在发生。无论如何,它现在工作正常。以上是关于具有私有并发类型的 NSManagedObjectContext 在主线程上执行块的主要内容,如果未能解决你的问题,请参考以下文章
目标 c - 核心数据:无法调用 NSManagedObject 子类的私有方法
具有两个不同核心数据 NSManagedObject 实体的 NSTreeController
如何在 NSManagedObject 子类中使用 Transformable 属性作为其实际类型?
将 NSManagedObject 数组与另一个“对象”类型 Swift 2 的数组进行比较
“NSManagedObject”类的 NSManagedObject 必须具有有效的 NSEntityDescription