iOS- Exception Type: 00000020:什么是看門狗機制


 

1.前言  

 
 前幾天我們項目閃退之后遇到的一個Crash,之后逛了許多論壇,博客都沒有找到滿意的回復
 在自己做了深入的研究之后,對iOS的看門狗機制有了一個基本的了解
 而有很多奇怪的Crash可能恰恰就是因為iOS的看門狗機制導致的
 今天分享出來,希望能幫助到后來者,下面我們先來看看Crash Report
 

2. iOS App Crash Report 分析

Date/Time: 2016-01-25 12:19:48.746 +0100
Launch Time: 2016-01-22 15:12:37.422 +0100
OS Version: iOS 8.4 (12H143)
Report Version: 105

Exception Type: 00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread: 0

Application Specific Information:
<BKNewProcess: 0x12cd26cf0; com.scasy.Dinnn; pid: 248; hostpid: -1> has active assertions beyond permitted time:
{(
<BKProcessAssertion: 0x12ce1b400> id: 248-C89C6FAD-B496-46ED-B59A-20D976A02D10 name: Called by ExternalAccessory, from <redacted> process: <BKNewProcess: 0x12cd26cf0; com.scasy.Dinnn; pid: 248; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:248 preventSuspend preventIdleSleep preventSuspendOnSleep
)}

Elapsed total CPU time (seconds): 0.130 (user 0.130, system 0.000), 1% CPU
Elapsed application CPU time (seconds): 0.044, 0% CPU

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x342ec474 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x342ec269 mach_msg + 37
2 CoreFoundation 0x25a1256f __CFRunLoopServiceMachPort + 143
3 CoreFoundation 0x25a10b15 __CFRunLoopRun + 1013
4 CoreFoundation 0x2595d1fd CFRunLoopRunSpecific + 473
5 CoreFoundation 0x2595d00f CFRunLoopRunInMode + 103
6 Foundation 0x266c7139 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 261
7 Foundation 0x26715221 -[NSRunLoop(NSRunLoop) run] + 77
8 Dinnn 0x0014af59 -[ConnectServerViewController updateInitDinnnThread:] (ConnectServerViewController.m:425)
9 Foundation 0x2678c5cb __NSThreadPerformPerform + 383
10 CoreFoundation 0x25a12fad __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 13
11 CoreFoundation 0x25a123bb __CFRunLoopDoSources0 + 215
12 CoreFoundation 0x25a10a21 __CFRunLoopRun + 769
13 CoreFoundation 0x2595d1fd CFRunLoopRunSpecific + 473
14 CoreFoundation 0x2595d00f CFRunLoopRunInMode + 103
15 GraphicsServices 0x2d2d81fd GSEventRunModal + 133
16 UIKit 0x29129a05 UIApplicationMain + 1437
17 Dinnn 0x00088c47 main (main.m:17)
18 libdyld.dylib 0x34235aad start + 1

 

我們先定位異常類型: Exception Type: 00000020
簡而言之,Exception Type: 00000020 意味着你正在做的異步網絡在主線程,當連接或運行緩慢,應用程序可以終止iOS。這將隨機發生。
 
最常見的原因是在一個網絡中的應用程序的看門狗超時崩潰是同步網絡的主要線程。
這里有三個因素:
1.同步網絡-這是您的網絡請求和阻止等待響應的地方。
 
2.主線程-同步網絡一般不理想,但它會導致特定問題,如果你在主線程上做的話。請記住,主線程負責運行用戶界面。如果你阻塞主線程的任何顯着的時間,用戶界面變得很遲鈍。
 
3.長期超時-如果網絡消失了(例如,用戶是在火車進入隧道),任何掛起的網絡請求不會失敗直到超時過期了。大多數網絡超時是以分鍾計算,即阻塞同步網絡請求在主線程可以同時保持用戶界面的響應時間。
 
試圖通過減少網絡超時來避免這個問題是一個不好的想法。在某些情況下,它可以采取許多秒的網絡請求成功,如果你總是提前時間,那么你永遠不會取得任何進展。
 
看門狗-為了保持用戶界面的響應,iOS系統包括一個看門狗機制。如果您的應用程序未能響應某些用戶界面事件(啟動、暫停、恢復、終止)的時間,該看門狗將殺死您的應用程序,並產生一個看門狗超時崩潰報告。
 
這個問題的一個棘手的方面是,它高度依賴於網絡環境。如果你總是在你的辦公室里測試你的應用,在你的網絡連接是好的,你永遠不會看到這種類型的崩潰。然而,一旦你開始部署你的應用程序,最終用戶誰會運行在各種網絡環境崩潰,像這樣。
 
總結,如果您在主線程上進行同步聯網呼叫,您的應用程序將受到看門狗超時崩潰,當它部署到一個廣泛的環境。
 
從上面的Crash report中的
6,7,行我們能看到具體原因, 8 行 我們可以看到具體位置。
 
具體:
 
關於-(BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)date;方法
指定runloop模式來處理輸入源,首個輸入源或date結束退出。
暫停當前處理的流程,轉而處理其他輸入源,當date設置為[NSDate distantFuture](將來,基本不會到達的時間),所以除非處理其他輸入源結束,否則永不退出處理暫停的當前處理的流程。
 
報告里很明顯告訴我們這里被堵塞了,說明這個Run loop當前是在主線程上,所以最后我們的APP被iOS的看門狗機制殺死了。
 
 
終:
 
一旦你確認這個問題與你的網絡代碼相關,有一個共同的解決方案:
異步網絡-這個問題的最佳解決方案是異步運行您的網絡代碼。異步網絡代碼有很多優點,至少是它可以讓你安全地訪問網絡,而不必擔心線程。
 
在輔助線程同步網絡如果它運行你的網絡代碼異步的比登天還難(也許你有一個大的便攜式的代碼庫,假定同步組網工作),你可以通過在輔助線程上運行你的同步碼避免看門狗。
 
如何異步運行網絡代碼,包括多線程這個你可以查看Apple文檔相關資料
關於iOS看門機制還有什么不懂歡迎留言。
 
作者: 清澈Saup
出處: http://www.cnblogs.com/qingche/
本文版權歸作者和博客園共有,歡迎轉載,但必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM