Ios &引用;performBlockAndWait:“执行锁定和等待”;块未被执行
我有一个类似的方法:Ios &引用;performBlockAndWait:“执行锁定和等待”;块未被执行,ios,core-data,concurrency,nsmanagedobjectcontext,Ios,Core Data,Concurrency,Nsmanagedobjectcontext,我有一个类似的方法: - (void)handleUpdate { dispatch_sync(dispatch_get_main_queue(), ^{ NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"]; [self.privateContext performBlockAndWait: ^{ // Some processing
- (void)handleUpdate
{
dispatch_sync(dispatch_get_main_queue(), ^{
NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"];
[self.privateContext performBlockAndWait: ^{
// Some processing
}];
});
}
我所称的mainContext
与主队列相关联,privateContext
与私有队列相关联,并且是mainContext
的子级。此方法是从privateContext
的私有队列调用的,当到达performBlockAndWait:
调用时,它不是nil
,但执行不会进入块,也不会到达此方法后的任何代码
我会错过什么
提前谢谢
EDIT:我在Xcode中没有得到错误,我在performBlockAndWait:
块内的代码中设置的断点以及在该方法调用之后都没有到达
编辑2:我更正了代码片段,我没有访问
mainContext
,而是访问与mainContext
关联的对象数组。好吧,在您的情况下,至少有一件事是错误的:
在主线程上调用performBlockAndWait:
(通过将其传递到主队列)。文档中说,performBlockAndWait:
在接收方队列上同步执行给定的块
作为该调用的结果,您将在主线程上获得死锁(当您在外部使用dispatch\u sync
时)
以dispatch\u async
方式更新:
问题不会消失。这是因为您仍在使用主队列(这意味着最后的主线程)和主CD上下文(这也意味着主线程)。问题是您让主线程等待作业在同一个(主线程)上完成线程-只是一个死锁。好吧,在你的情况下,至少有一件事是错误的: 在主线程上调用
performBlockAndWait:
(通过将其传递到主队列)。文档中说performBlockAndWait:
在接收方队列上同步执行给定的块
作为该调用的结果,您将在主线程上获得死锁(当您在外部使用dispatch\u sync
时)
以dispatch\u async
方式更新:
问题不会消失。这是因为您仍在使用主队列(这意味着最后的主线程)和主CD上下文(这也意味着主线程)。问题是您让主线程等待作业在同一个(主线程)上完成线程-只是一个开箱即用的死锁。如果如您所说,从私有队列调用了
handleUpdate
,那么这是一个典型的死锁
您在专用队列上调用dispatch\u sync
。这意味着“等待此消息返回,然后再继续此队列”。然后,在该块中,您将另一个必须等待在专用队列上运行的块排入队列,该块在运行之前不会返回。队列现在正在等待自身,并且永远不会前进
我怀疑您希望这里的
dispatch\u sync
是dispatch\u async
。如果像您所说的那样从专用队列调用handleUpdate
,那么这是一个典型的死锁
您在专用队列上调用dispatch\u sync
。这意味着“等待此消息返回,然后再继续此队列”。然后,在该块中,您将另一个必须等待在专用队列上运行的块排入队列,该块在运行之前不会返回。队列现在正在等待自身,并且永远不会前进
我怀疑您希望这里的
dispatch\u sync
是dispatch\u async
。您有几个问题
首先,您直接使用GCD来序列化对NSMainQueueConcurrency
MOC的访问。您应该永远不要使用除CoreData同步机制之外的任何方法来访问CoreData。是的,从主线程访问NSMainQueueConcurrencyType
MOC是安全的。但是,您永远不要使用GCD直接…尤其是调度\u sync
第二,你使用的是<代码> DeXCHYSYNC 这是不可重入的。它可以,也会导致死锁。你几乎不应该使用这个函数。 第三,您正在对子上下文调用
performBlockAndWait
,这是绝对不应该做的,因为它会导致死锁。一般来说,除非您真的知道自己在做什么,否则您应该避免使用非异步线程模型
您的代码应该更像这样。每个performBlock
调用都会将一个块发布到消息队列中,消息队列将独立于任何等待的线程进行处理
- (void)handleUpdate
{
[self.mainContext performBlock:^{
NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"];
[self.privateContext performBlock: ^{
// Some processing with objectIDs
}];
});
}
你有几个问题 首先,您直接使用GCD来序列化对
NSMainQueueConcurrency
MOC的访问。您应该永远不要使用除CoreData同步机制之外的任何方法来访问CoreData。是的,从主线程访问NSMainQueueConcurrencyType
MOC是安全的。但是,您永远不要使用GCD直接…尤其是调度\u sync
第二,你使用的是<代码> DeXCHYSYNC 这是不可重入的。它可以,也会导致死锁。你几乎不应该使用这个函数。 第三,您正在对子上下文调用
performBlockAndWait
,这是绝对不应该做的,因为它会导致死锁。一般来说,除非您真的知道自己在做什么,否则您应该避免使用非异步线程模型
您的代码应该更像这样。每个performBlock
调用都会将一个块发布到消息队列中,消息队列将独立于任何等待的线程进行处理
- (void)handleUpdate
{
[self.mainContext performBlock:^{
NSArray *objectIDs = [self.objectsInMainContext valueForKeyPath:@"objectID"];
[self.privateContext performBlock: ^{
// Some processing with objectIDs
}];
});
}
有什么具体的原因让你去医院吗