次のコードは、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)」です。奇妙なことに、クラッシュ後に [続行] ボタンを押すと、通常どおり続行されます。
なぜこれがクラッシュするのですか?この動作を引き起こさずに長いタスクをキューに送信するにはどうすればよいですか?
これまでに私が試したことがいくつかありますが、謎にまったく光を当てていません:
- 独自のディスパッチ キューの作成(バックグラウンド スレッドのディスパッチ キューを含む)
- GCD の代わりに NSBlockOperation を使用する (依然としてクラッシュする)
- 挿入は眠る。短いスリープ (5 秒程度) は、スリープ時までにクラッシュを遅らせるようです。より長い睡眠はより多くのことをするようです. したがって、5 秒間 1 回スリープすると、4 分 15 秒ではなく 4 分 20 秒でクラッシュします。1 回 60 秒間スリープすると、クラッシュするまでに約 10 分かかりますが、最終的には発生します。この手がかりは重要なようですが、それが何を意味するのかわかりません。
アップデート #1
この問題は、GDB ではなく、LLDB でのみ再現されます。