2013-05-04 161 views
4

我有一个OSX应用程序,我正在使用父/子NSManagedObjectContext设置。孩子MOC有NSPrivateQueueConcurrencyType,是我主要使用的。父级设置为NSMainQueueConcurrencyTypeNSManagedObjectContext performBlockAndWait当从两个线程调用时导致死锁

当我从后台线程调用performBlockAndWait在从主线程调用它的同时,我得到死锁 - semaphore_wait_trap。暂停调试器显示两个线程都卡在performBlockAndWait

我该如何解决这个问题?我认为这种方法是专门针对这种情况设计的,只需将上下文的私有队列中的块排队,然后适当地返回?

回答

2

我通过创建一个串行队列,然后执行所有performBlock调用来确保它们不会互相混淆。老实说,我不确定这是否是好的做法,但它确实解决了我的特殊情况。

1

即使使用专用并发类型,NSManagedObjectContext仍然不是线程安全的。

performBlock:and performBlockAndWait:只确保块操作在为上下文指定的队列上执行。

您仍然可以使用performBlockAndWait:获取死锁,因为它会阻止当前正在执行的线程,直到它返回。 performBlockAndWait内发生了什么:?可能是需要访问主线程的东西,这就是为什么它是死锁的。

你可以使用performBlock:取而代之吗?

+0

嗯我可以尝试和切换我的代码执行块是的,肯定会更长的回调等,但完全有可能我敢肯定。那么通过使用这种方法,块将以线程安全的方式执行? – 2013-05-04 23:17:44

+0

performBlock和performBlockAndWait只是确保您传递给它们的块在与托管对象上下文相关的正确队列上执行。所以是的,你的块将在上下文中以线程安全的方式执行 - 不同之处在于你的代码的语义,如果你需要阻塞并等待块完成。我会一直努力首先使用performBlock并使用performBlockAndWait,如果不得不出于任何原因。请参阅http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/index.html – bandejapaisa 2013-05-05 06:41:00