PerformBlockAndWait 造成死锁

2023-12-26

我正在编写一个执行一些 CoreData 操作的函数。我希望该函数仅返回after所有 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) 谁能解释一下为什么会出现这种僵局?

and

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

谢谢你!


假设您正在打电话myFunction从主线程。让我们想象一下[DatabaseDelegate sharedDelegate].parent.managedObjectContext被安排在主线程上。

With [backgroundContext performBlockAndWait:]您正在上下文私有后台队列上调度一个块。阻塞主线程。

With [.parent.managedObjectContext performBlockAndWait:],您正在主线程上调度一个块,从而阻塞专用队列。

但主线程已经被阻塞了。所以该块永远不会执行。和performBlockAndWait:永远不会回来。

僵局。

使用异步调度块和完成块。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PerformBlockAndWait 造成死锁 的相关文章

随机推荐