You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Run Loop是同步还是异步?为何我的代码未出现预期死锁?

为什么这段Objective-C代码未出现预期死锁?

问题代码

- (void)viewDidLoad {
  [super viewDidLoad];
  
  __block BOOL completed = NO;
  [self doMyWork:^{ 
    completed = YES;
  }];
  
  while (!completed) {
    [NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
  }
}

核心疑问

原本判断这段代码会形成死锁:completion block在主线程运行,需viewDidLoad返回才能执行;而viewDidLoad要返回,又依赖completion block触发completed标志,形成循环等待。但实际运行未出现死锁,哪里理解有误?

原因解析

问题出在对NSRunLoop工作机制的误解:

  • 当调用[NSRunLoop.currentRunLoop runUntilDate:]时,主线程的RunLoop会进入一个临时的处理周期,在这个周期内它会处理当前主线程队列中已等待的所有事件,包括待执行的block。
  • 如果doMyWork:是将completion block异步派发到主线程队列(比如通过dispatch_async),那么在RunLoop临时运行的过程中,这个block会被执行,completed被设为YES,循环随即终止,不会出现死锁。
  • 即使doMyWork:是同步执行completion block,completed会被立刻赋值为YES,while循环根本不会启动,自然也不会产生死锁。

只有当completion block必须等到viewDidLoad执行完毕后,RunLoop进入下一轮自然循环才会执行,同时viewDidLoad又卡在等待block执行时,才会触发死锁。但你的代码通过手动调用RunLoop,主动触发了事件处理,打破了这个循环等待的条件。

内容的提问来源于stack exchange,提问作者OMGPOP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:47:38