Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/100.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios &引用;performBlockAndWait:“执行锁定和等待”;块未被执行_Ios_Core Data_Concurrency_Nsmanagedobjectcontext - Fatal编程技术网

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
        }];
    });
}

有什么具体的原因让你去医院吗