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/
本文版权归做者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接。
相关文章
相关标签/搜索