How to determine which NSNotification is crashing due to dealloc-ed observer
Question
The golden rule of using NSNotification
seems to be
"call
removeObserver
before theobserver
(or theobject
) is deallocated".
I'm dealing with a codebase where this rule hasn't been followed, but I can't locate the transgression. I've searched through the code and ensured that every addObserver
has a matching removeObserver
but I'm still seeing crash reports of the following variety:
OS Version: iPhone OS 5.0.1 (9A405)
Report Version: 104
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x8
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x31516fbc objc_msgSend + 16
1 Foundation 0x3195b50f __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 19
2 CoreFoundation 0x37a02577 ___CFXNotificationPost_block_invoke_0 + 71
3 CoreFoundation 0x3798e0cf _CFXNotificationPost + 1407
4 Foundation 0x318cf3fb -[NSNotificationCenter postNotificationName:object:userInfo:] + 67
5 UIKit 0x34e5ee25 -[UIApplication _handleApplicationSuspend:eventInfo:] + 697
6 UIKit 0x34deed17 -[UIApplication handleEvent:withNewEvent:] + 2031
7 UIKit 0x34dee3bf -[UIApplication sendEvent:] + 55
8 UIKit 0x34dedd2d _UIApplicationHandleEvent + 5809
9 GraphicsServices 0x3750bdf3 PurpleEventCallback + 883
10 CoreFoundation 0x37a0a553 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 39
11 CoreFoundation 0x37a0a4f5 __CFRunLoopDoSource1 + 141
12 CoreFoundation 0x37a09343 __CFRunLoopRun + 1371
13 CoreFoundation 0x3798c4dd CFRunLoopRunSpecific + 301
14 CoreFoundation 0x3798c3a5 CFRunLoopRunInMode + 105
15 GraphicsServices 0x3750afcd GSEventRunModal + 157
16 UIKit 0x34e1c743 UIApplicationMain + 1091
17 App 0x00002d2f main (main.m:14)
My interpretation of this crash report is that [UIApplication _handleApplicationSuspend:eventInfo:]
is posting a notification for which an observer has been deallocated before being removed.
Assuming this interpretations is correct, how would I go about determining which notification is being posted? And ideally, what the deallocated object type?
Solution
You can set a symbolic breakpoint in -[NSNotificationCenter postNotificationName:object:userInfo:]
and print the third argument passed to it (the first being the NSNotificationCenter
, the second, _cmd
) using the debugger po
command.
OTHER TIPS
Another way to determine this is to get the name parameter value (the string you passed for posting the notification) and verify that any object that is observing that string/name is set to remove observation sometime in the objects lifecycle or as it is deallocating.