以下代码在 iOS 模拟器中产生崩溃。
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
NSDate *sleepStart = [NSDate date];
while ([sleepStart timeIntervalSinceNow] > -300) {
}
});
}
更新:即使在后台线程上也会出现此问题。
下面的代码也有问题:
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSDate *sleepStart = [NSDate date];
while ([sleepStart timeIntervalSinceNow] > -300) {
}
});
}
就这样。将其粘贴到任何视图控制器中,在模拟器中运行该应用程序正好 4 分 15 秒,它就会崩溃。
崩溃是我以前从未见过的类型。它是“EXC_??? (11)”。奇怪的是,您可以在崩溃后按下继续按钮,它会像往常一样继续。
为什么会崩溃?如何在不导致此行为的情况下将长任务提交到队列?
以下是我迄今为止尝试过的一些事情,但对这个谜团没有任何启示:
- 创建我自己的调度队列(包括后台线程)
- 使用 NSBlockOperation 而不是 GCD(仍然崩溃)
- 插入睡眠。短暂的睡眠(不到 5 秒左右)似乎在睡眠时延迟了崩溃。更长的睡眠似乎有更多的作用。所以如果你睡一次五秒钟,它会在 4m 20s 而不是 4m 15s 时崩溃。如果你睡一次 60 秒,大约需要十分钟的时间来崩溃,但它最终会发生。这个线索似乎很重要,但我不知道它可能意味着什么。
更新#1
该问题仅在 LLDB 下重现,而不在 GDB 下重现。