我有一个传递给另一个函数的dispatch_block_t
,当函数完成异步任务时,将调用此块。但问题是我不知道这个块会被调用哪个线程。
我想在主线程中更新我的 UI,因此我想使用
dispatch_async(dispatch_get_main_queue(), ^{...})
以更新我的用户界面。但恐怕如果发生这种情况会造成僵局
dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
dispatch_async(queue, ^{
// outer block is waiting for this inner block to complete,
// inner block won't start before outer block finishes
// => deadlock
});
// this will never be reached
});
有没有办法防止僵局?就像在不使用dispatch queue
的情况下更新 UI 元素一样。是否可以创建要self
weak reference
以更新 UI?
尝试使用 NSLogs 运行您的示例,您会注意到不会发生死锁。这是因为使用dispatch_async
只是将块提交到队列,而无需等待它完成执行(与dispatch_sync
相反(。
所以运行这段代码:
dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
});
NSLog(@"3");
});
将生成以下日志:
Testtt[32153:2250572] 1
Testtt[32153:2250572] 3
Testtt[32153:2250572] 2
此外,我担心在这里使用dispatch_async(dispatch_get_main_queue(), ^{...})
是常用的技术,可确保消费者在主线程上获得结果(即消费者不"关心"线程(。
但是,为什么使用dispatch_block_t
来传递完成块?在我看来,在消费者端使用这样的东西有点令人困惑 - 我会传递一个匿名(没有 typedef(块或为这些简单的完成块创建我自己的 typedef。