我正在编写一个执行一些CoreData东西的函数。我希望该函数仅在执行完所有CoreData操作之后返回。 CoreData的工作包括在后台上下文中创建一个对象,然后在父上下文中做更多的事情:

+ (void) myFunction
    NSManagedObjectContext *backgroundContext = [DatabaseDelegate sharedDelegate].backgroundContext;

    [backgroundContext performBlockAndWait:^{
      MyObject *bla = create_my_object_in:backgroundContext;

      [backgroundContext obtainPermanentIDsForObjects:[[backgroundContext insertedObjects] allObjects] error:nil];
      [backgroundContext save:nil];

      [[DatabaseDelegate sharedDelegate].parent.managedObjectContext performBlockAndWait:^{
        [[DatabaseDelegate sharedDelegate].parent updateChangeCount:UIDocumentChangeDone];

        // Do some more stuff
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [queue addOperation:someOperation];
      }];
    }];
   return;
}

我希望返回仅在[queue addOperation:someOperation]之后发生。
这似乎在大多数情况下都有效,但是在我遇到一种情况时,此函数永不返回。似乎已陷入僵局,我怀疑这是因为performBlockAndWait

我的问题是:

(1)有人可以解释为什么会发生这种僵局吗?



(2)实现相同功能的正确方法是什么?要求是myFunction仅在两个块均已执行后才返回。

谢谢!

最佳答案

假设您正在从主线程调用myFunction。让我们想象[DatabaseDelegate sharedDelegate].parent.managedObjectContext是在主线程上调度的。

使用[backgroundContext performBlockAndWait:],您可以在上下文私有(private)背景队列上调度一个块。阻塞主线程。

使用[.parent.managedObjectContext performBlockAndWait:],您可以在主线程上调度一个块,从而阻塞私有(private)队列。

但是主线程已经被阻塞。因此,该块将永远不会执行。 performBlockAndWait:将永远不会返回。

僵局。

将异步计划的块与完成块一起使用。

10-07 19:37