我正在使用GCD的dispatch_after
方法當我的應用程序正在加載執行某些行爲。預期的行爲是從applicationDidFinishLaunchingWithOptions
的末尾等待3秒鐘以執行在後臺隊列中運行的選擇器。GCD dispatch_after調用導致SIGBUS信號
我的測試設備上沒有遇到任何崩潰,但我遇到了未捕獲的SIGBUS信號的用戶崩潰報告,原因是BUS_ADRALN異常。根據我對此代碼的理解,BUS_ADRALN錯誤表示地址對齊錯誤。
這是我如何創建我的定時器:
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
^(void){
[self methodToPerformInBackground];
});
什麼導致這個崩潰?
由於多線程錯誤可能是一種奇怪的怪物,我會拋出一些我一直在腦海中徘徊的想法。
- 我打來電話給
[self performSelectorOnMainThread:withObject:waitUntilDone]
。在這種稱爲選擇器的選擇器中執行此操作有什麼問題嗎? - 由於我打電話
dispatch_get_global_queue
而不是dispatch_create_queue
,我不需要保留此方法返回的隊列。這個推理是否正確? - 在此代碼中,
self
是應用程序委託。嘗試在應用程序進入後臺或終止後執行該塊會導致崩潰嗎?應用程序在關閉時是否自動清理所有調度的塊? - 被調用方法內部的東西導致崩潰,但GCD不提供堆棧跟蹤。
編輯:我寧願不包括被稱爲該塊中的代碼,因爲我不相信這是最主要的問題,反正。這是堆棧跟蹤。線程0上的崩潰使得它好像是GCD中的問題,而不是塊中調用的代碼。
編輯#2:通過更多的崩潰報告後,我有奇怪的消息分享。這個崩潰只出現在運行iOS 4.2.X及更低版本的用戶上。由於GCD支持iOS 4.0及更高版本,我的猜測是4.3中有一個錯誤修正。
Thread 0 Crashed:
0 libSystem.B.dylib 0x35e5fb10 _dispatch_retain + 0
1 libSystem.B.dylib 0x35e5df8c dispatch_after_f + 80
2 libSystem.B.dylib 0x35e5e070 dispatch_after + 72
3 MyApplication 0x0000466c -[MyApplicationDelegate applicationDidFinishLaunchingPart2:] (MyApplicationDelegate.m:366)
4 CoreFoundation 0x37538f79 -[NSObject(NSObject) performSelector:withObject:] + 25
5 Foundation 0x35171e6d __NSThreadPerformPerform + 273
6 CoreFoundation 0x375518d1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
7 CoreFoundation 0x37521ecd __CFRunLoopDoSources0 + 385
8 CoreFoundation 0x375216f9 __CFRunLoopRun + 265
9 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
10 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
11 GraphicsServices 0x33e76d24 GSEventRunModal + 196
12 UIKit 0x3591d57c -[UIApplication _run] + 588
13 UIKit 0x3591a558 UIApplicationMain + 972
14 MyApplication 0x00003024 main (main.m:113)
Thread 1:
0 libSystem.B.dylib 0x35d8f974 kevent + 24
1 libSystem.B.dylib 0x35e5dd70 _dispatch_queue_invoke + 104
2 libSystem.B.dylib 0x35e5d790 _dispatch_worker_thread2 + 128
3 libSystem.B.dylib 0x35de6978 _pthread_wqthread + 400
Thread 2:
0 libSystem.B.dylib 0x35de72fc __workq_kernreturn + 8
Thread 3:
0 libSystem.B.dylib 0x35d5b3b0 mach_msg_trap + 20
1 CoreFoundation 0x37521f83 __CFRunLoopServiceMachPort + 95
2 CoreFoundation 0x37521787 __CFRunLoopRun + 407
3 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
4 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
5 WebCore 0x3318bd1c _ZL12RunWebThreadPv + 532
6 libSystem.B.dylib 0x35de5b4c _pthread_start + 372
Thread 4:
0 libSystem.B.dylib 0x35d5b3b0 mach_msg_trap + 20
1 CoreFoundation 0x37521f83 __CFRunLoopServiceMachPort + 95
2 CoreFoundation 0x37521787 __CFRunLoopRun + 407
3 CoreFoundation 0x3752150b CFRunLoopRunSpecific + 227
4 CoreFoundation 0x37521419 CFRunLoopRunInMode + 61
5 Foundation 0x3517ec55 +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] + 217
6 Foundation 0x3515cb91 -[NSThread main] + 49
7 Foundation 0x35155b97 __NSThread__main__ + 915
8 libSystem.B.dylib 0x35de5b4c _pthread_start + 372
如果您聲稱發生了崩潰,需要查看該方法中的代碼。否則,我們應該怎麼做? – borrrden
@borrrden,該方法中有太多的代碼需要共享。該方法正在執行一些文件IO並讀取原子(但不是線程安全的)屬性值。我雖然添加了堆棧跟蹤。如果這沒有幫助,我會添加一些代碼。 – goldierox
你是否靜態分析過你的代碼?在3秒的發送之前您是否在屏幕上顯示任何內容? – Nico