我有一个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元素一样。是否可以创建weak reference
到self
来更新UI?
答案 0 :(得分:1)
尝试使用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。