实战:Bad Access
因为在ARC 问世后,Bad Access 造成的crash 的确少很多,所以在这边放的是一份在2012 年时为了解释Bad Access 是如何形成而留下来的crash report,但内容不是很完整,只保留了发生Bad Access 时的thread。
这是在2012 年时Pinterest App 发生的crash,可以注意到当时是在iPhone 4S 上使用iOS 5 操作系统。在这份crash report 中,可以清楚看到iOS 5 之前如何处理内存不足警告的流程。
从run loop中,UIApplication首先收到了记忆体不足警告,UIApplication接着就透过Notification Center通知所有的view controller记忆体不足,我们在记忆体管理Part 3 - Memory Warnings提过,iOS 5之前,只要发生记忆体警告,就会要求所有不是在最前景的view controller将自己的view释放掉,purgeMemoryForReason:
与unloadViewForced:
在做的,就是强迫释放view这件事情。在强迫释放view发生crash,于是可以推断,就算我们没有把Pinterest的crash report解开,也可以看出,0x0005995e这个位置会是某个view controller的viewDidUnload
。
虽然iOS 5就推出了ARC,但当时很多在iOS 5问世之前就写出来的App,并没有立刻转换到ARC架构上,这份crash report呈现了当时这段转换期。另外,我们在常见Crash的类型也提到,在viewDidUnload
最容易发生的,就是忘记像UIButton这种建立时就是auto release的物件给retain起来,然后在viewDidUnload
的时候多release了一次。
Incident Identifier: 3486ADCD-070E-43C8-ADC0-44E254DB92E8
CrashReporter Key: babb1c6e8923eb91911e323103f4d82fa0bc7fe2
Hardware Model: iPhone4,1
Process: Pinterest [12210]
Path: /var/mobile/Applications/4BFAD77B-FCE9-4EE1-A36D-ADFA55303130/Pinterest.app/Pinterest
Identifier: Pinterest
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2012-03-20 09:19:27.054 +0800
OS Version: iPhone OS 5.1 (9B179)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x20aba07b
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x35839f78 objc_msgSend + 16
1 Pinterest 0x0005995e 0x1000 + 362846
2 UIKit 0x33a84bd8 -[UIViewController unloadViewForced:] + 244
3 UIKit 0x33bcc492 -[UIViewController purgeMemoryForReason:] + 58
4 Pinterest 0x000a2df4 0x1000 + 663028
5 Pinterest 0x000594f0 0x1000 + 361712
6 Foundation 0x37b634f8 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 12
7 CoreFoundation 0x37305540 ___CFXNotificationPost_block_invoke_0 + 64
8 CoreFoundation 0x37291090 _CFXNotificationPost + 1400
9 Foundation 0x37ad73e4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 60
10 Foundation 0x37ad8c14 -[NSNotificationCenter postNotificationName:object:] + 24
11 UIKit 0x33b9726a -[UIApplication _performMemoryWarning] + 74
12 UIKit 0x33b97364 -[UIApplication _receivedMemoryNotification] + 168
13 libdispatch.dylib 0x345942da _dispatch_source_invoke + 510
14 libdispatch.dylib 0x34591b7a _dispatch_queue_invoke$VARIANT$mp + 46
15 libdispatch.dylib 0x34591eba _dispatch_main_queue_callback_4CF$VARIANT$mp + 150
16 CoreFoundation 0x3730c2a6 __CFRunLoopRun + 1262
17 CoreFoundation 0x3728f49e CFRunLoopRunSpecific + 294
18 CoreFoundation 0x3728f366 CFRunLoopRunInMode + 98
19 GraphicsServices 0x3219c432 GSEventRunModal + 130
20 UIKit 0x33a13e76 UIApplicationMain + 1074
21 Pinterest 0x0000328a 0x1000 + 8842
22 Pinterest 0x00003248 0x1000 + 8776