以下代碼在iOS模擬器中產生崩潰。GCD與超過255秒的任何任務崩潰
- (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秒左右)似乎可以延緩睡眠時的崩潰。更長的睡眠似乎做了更多。所以如果你一次睡五秒鐘,它將會以4米20秒的速度而不是4米15秒的速度崩潰。如果你一次睡60秒,大概需要十分鐘才能崩潰,但最終會發生。這個線索似乎很重要,但我不知道它可能意味着什麼。
更新#1
的問題僅LLDB,不GDB下再現。
你舉起了主線?是的,它會崩潰。 – 2013-03-04 03:38:23
爲了擴大這個範圍:iOS發現你的應用一直沒有響應(對任何事件沒有響應)時間過長,並且因爲這意味着你的應用被破壞,它會殺死你的應用。你不應該超過1/60秒,更不用說4分鐘了。爲什麼不在一個併發隊列中運行此塊? – 2013-03-04 03:42:59
問題更新後,行爲與主隊列是否被阻止或後臺隊列無關。 – Drew 2013-03-04 05:29:28