官方翻译:
异常调用栈
Thread 0:
0 libSystem.B.dylib 0x00001668 mach_msg_trap + 20
1 libSystem.B.dylib 0x00003734 mach_msg + 44
2 CoreFoundation 0x0002296e CFRunLoopRunSpecific + 1150
3 CoreFoundation 0x000224da CFRunLoopRunInMode + 42
4 CFNetwork 0x0002b118 CFURLConnectionSendSynchronousRequest + 244
5 Foundation 0x000a45a2 +[NSURLConnection sendSynchronousRequest:returningResponse[…]
6 MyBadApp 0x000063f6 0x1000 + 21494
7 MyBadApp 0x0000630a 0x1000 + 21258
8 MyBadApp 0x00006ada 0x1000 + 23258
9 MyBadApp 0x00003618 0x1000 + 9752
10 MyBadApp 0x0000351e 0x1000 + 9502
11 MyBadApp 0x00003874 0x1000 + 10356
12 UIKit 0x00068568 -[UIViewController viewWillMoveToWindow:] + 76
13 UIKit 0x0000988a -[UIView(Hierarchy) _willMoveToWindow:withAncestorView:] + 126
14 UIKit 0x00005e6e -[UIView(Internal) _addSubview:positioned:relativeTo:] + 222
15 UIKit 0x00005d80 -[UIView(Hierarchy) addSubview:] + 16
16 MyBadApp 0x000028d2 0x1000 + 6354
17 UIKit 0x00003e58 -[UIApplication _performInitializationWithURL:payload:] + 336
18 UIKit 0x00003b22 -[UIApplication _runWithURL:payload:launchOrientation:] + 394
19 UIKit 0x0004f8c4 -[UIApplication handleEvent:withNewEvent:] + 1336
20 UIKit 0x0004f242 -[UIApplication sendEvent:] + 38
21 UIKit 0x0004ec8c _UIApplicationHandleEvent + 4772
22 GraphicsServices 0x00003b2c PurpleEventCallback + 660
23 CoreFoundation 0x00022d96 CFRunLoopRunSpecific + 2214
24 CoreFoundation 0x000224da CFRunLoopRunInMode + 42
25 UIKit 0x0000340a -[UIApplication _run] + 342
26 UIKit 0x00001954 UIApplicationMain + 636
27 MyBadApp 0x00002828 0x1000 + 6184
28 MyBadApp 0x000027f8 0x1000 + 6136
看看栈的5、6行,你能看到应用程序正在使用同步网络调用 (+[NSURLConnection sendSynchronousRequest:returningResponse:error:]) 已经被阻塞并等待网络,thereby invoking the ire of the watchdog.
一旦你确认了这个问题和你的网络代码相关,通常有两种解决方案:
- 异步网络 - 解决这个问题最好的方法就是异步运行你的网络代码,异步网络代码有很多优点,不只是让你安全的访问网络,不用担心线程。
- 在第二线程同步网络操作 - 如果异步运行网络代码非常困难(假如你使用了大量基于同步网络的可移植代码,你能避开watchdog,在第二线程上执行同步代码)。
需要认识到隐藏在抽象层后面的同步网络操作掩盖了一个危险。
如果你用"http"或"https"URL方式调用 -[NSXMLParser -initWithContentsOfURL:],NSXMLParser会同步下载这个URL的内容。这是非常方便的,但是如果你在主线程运行它,有被看门口watchdog杀掉的风险。一个更好的选择就是异步下载URL的内容到wenjian,然后使用''file"URL调用-[NSXMLParser -initWithContentsOfURL:] 方法。这同样适用于其他"WithContentsOfURL",像+[NSString stringWithContentsOfURL:encoding:error:], -[NSDictionary initWithContentsOfURL:]等等。
reachability — The System Configuration framework reachability API (<SystemConfiguration/SCNetworkReachability.h>) 默认是同步操作。因此像SCNetworkReachabilityGetFlags这种看起来没有问题的API可能使你被watchdog杀死。如果你使用了reachability API,你应该异步调用。这涉及到在run loop上使用 SCNetworkReachabilityScheduleWithRunLoop 方法去执行你的reachability 查询。