2015-10-05 29 views
0

我有一个类似的方法:“performBlockAndWait:”块不执行

- (void)handleUpdate 
{ 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"]; 

     [self.privateContext performBlockAndWait: ^{ 
     // Some processing 
     }]; 
    }); 
} 

我叫mainContext关联到主队列,并privateContext关联到一个专用队列,是mainContext的孩子。这种方法是从privateContext的私有队列调用,而且它不是nil达到performBlockAndWait:呼叫时,但执行不进入块既不达到此方法后的任何代码...

我该怎么办在这里失踪?

在此先感谢

编辑:我得到在Xcode中没有错误,我已经在performBlockAndWait:块内,调用此方法后代码中设置断点只是没有达到。

编辑2:我校正代码段,我没有访问mainContext但关联到mainContext对象的数组。

+0

任何特定的原因,当你已经在私人环境中的第一个地方时,你为什么得到主要上下文来获取对象ID? – Mundi

+0

@Mundi对不起,该行是错误的...我编辑问题 – AppsDev

+0

@Mundi我需要将'mainContext'中的对象传递给这个子上下文来执行我的更新。 – AppsDev

回答

0

好吧,至少有1两件事是错在你的情况:

调用主线程performBlockAndWait:(通过它传递给主队列)。该文档说performBlockAndWait:

在接收器的队列上同步执行给定的块。

由于这一呼吁的结果,你会得到在主线程死锁(如你使用dispatch_sync外面的dispatch_async方式

UPDATE:。 的问题不会消失那是因为你将仍然使用主队列(这意味着最后的主线程)和主CD上下文(这也意味着主线程)。问题在于,您需要等待主线程等待作业完成相同(主)线 - 只是开箱即用的死锁

+0

因为我需要访问块内的'objectIDs',这应该是最好的方法:从异步线程调用不同于'privateContext'专用队列的'handleUpdate',或者使用'dispatch_async'获取主线程? – AppsDev

+1

我怀疑需要使用同步方法。但是,如果是这样,只需删除封闭的dispatch_sync - 但使用NSPrivateQueueConcurrencyType(使用 - (instancetype)initWithConcurrencyType:(NSManagedObjectContextConcurrencyType)类型)初始化您的上下文。 –

+0

我使用'dispatch_async'来获取主队列,因为我需要访问主要上下文的对象,并且mai上下文与主线程相关联... – AppsDev

0

如果handleUpdate被调用私人队列如你所说,那么这是一个典型的僵局。

您在专用队列上拨打dispatch_sync。这意味着“等到这个返回,然后继续这个队列。”然后,在该块内部,您排队另一个必须等​​待在专用队列上运行的块,直到它结束才会返回。队列现在正在等待自己,永远不会进展。

我怀疑你想dispatch_sync这里是dispatch_async

+0

但我需要访问块内的'objectIDs'数组,不要使用'dispatch_async'会导致问题呢? – AppsDev

+0

从不同于privateContext的私有队列的异步线程中调用'handleUpdate'会更好吗,而不是使用'dispatch_async'来获得主队列? – AppsDev

+0

我不认为这里有一个单一的答案。您需要管理整个应用程序的并发性。确保你已经开始使用Core Data Concurrency部分:https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Conceptual/CoreData/Concurrency.html。通常情况下,您希望让Core Data通过'NSPrivateQueueConcurrencyType'处理并发性,而不是试图强制特定的队列。 –

0

你有几个问题。

首先,您正在使用GCD来直接访问NSMainQueueConcurrency MOC。你应该从来没有使用除了CoreData同步机制以外的任何访问CoreData。是的,从主线程访问NSMainQueueConcurrencyType MOC是安全的。但是,您不应该直接使用GCD ...尤其是dispatch_sync

其次,您使用的是不可重入的dispatch_sync。它可以,也会导致僵局。你几乎不应该使用这个功能。把它看作一个非常尖锐的工具,用于它是解决非常具体问题的唯一解决方案。

第三,您在子环境上调用performBlockAndWait,不应该这样做,因为它可能导致死锁。一般来说,除非你真的知道你在做什么,否则你应该避免使用非异步线程模型。

你的代码应该是更像这样的东西。每个performBlock调用都会​​将一个块发送到消息队列中,该消息队列将独立于任何等待的线程进行处理。

- (void)handleUpdate 
{ 
    [self.mainContext performBlock:^{ 
     NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"]; 
     [self.privateContext performBlock: ^{ 
      // Some processing with objectIDs 
     }]; 
    }); 
}