我正在编写一个函数来执行一些 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
仅在两个 block 都已执行后返回。
谢谢!
最佳答案
假设您正在从主线程调用 myFunction
。让我们想象一下 [DatabaseDelegate sharedDelegate].parent.managedObjectContext
被安排在主线程上。
使用 [backgroundContext performBlockAndWait:]
,您可以在上下文专用后台队列上安排一个 block 。阻塞主线程。
使用 [.parent.managedObjectContext performBlockAndWait:]
,您在主线程上调度一个 block ,阻塞私有(private)队列。
但是主线程已经被阻塞了。所以这个 block 永远不会执行。 performBlockAndWait:
永远不会返回。
死锁。
使用带有完成 block 的异步调度 block 。
关于objective-c - performBlockAndWait 创建死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12500627/