10

La regla de oro de la utilización de NSNotification parece sercómo determinar qué NSNotification está fallando debido a dealloc-ed observador

"llamada removeObserver antes de la observer (o el object) se desasigna".

Estoy tratando con una base de código donde no se ha seguido esta regla, pero no puedo localizar la transgresión. He buscado a través del código y se aseguró de que cada addObserver tiene un juego removeObserver pero todavía estoy viendo los informes de fallos de la siguiente variedad:

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) 

Mi interpretación de este informe de bloqueo es que [UIApplication _handleApplicationSuspend:eventInfo:] es la publicación de una notificación para que un observador ha sido desasignado antes de ser eliminado.

Suponiendo que estas interpretaciones son correctas, ¿cómo voy a determinar qué notificación se está publicando? E idealmente, ¿qué tipo de objeto desasignado?

Respuesta

6

se puede establecer un punto de ruptura simbólica en -[NSNotificationCenter postNotificationName:object:userInfo:] e imprimir el tercer argumento pasado a la misma (siendo el primero el NSNotificationCenter, el segundo, _cmd) usando el comando depurador po.

+0

idea genial. Me estaba acercando desde el ángulo de 'interceptación postNotificación en tiempo de ejecución', pero durante la depuración es una buena alternativa (y responde a la pregunta real). –

+3

Solo para agregar un poco más de detalle, agregué un punto de corte simbólico en '[NSNotificationCenter postNotificationName: object: userInfo:]' como se sugiere y establecí la "acción" del punto de interrupción en un "comando de depuración" de "po $ r2". Al ejecutar la aplicación en el dispositivo y suspenderla, veo muchas notificaciones publicadas durante '[UIApplication _handleApplicationSuspend: eventInfo:]' pero las únicas notificaciones que coinciden con la pila de llamadas de informe de fallos son 'UIApplicationSuspendedNotification' y' UIApplicationDidEnterBackgroundNotification' (predeciblemente) –

+0

Maravillosa respuesta. Me siento como si estuviera ciego antes. Si usa "po $ rdi" como el "comando del depurador" en Mac, puede ver el nombre de la notificación. – Charlesism

0

Otra forma de determinar esto es obtener el valor del parámetro del nombre (la cadena que pasó para publicar la notificación) y verificar que cualquier objeto que esté observando esa cadena/nombre esté configurado para eliminar la observación alguna vez en el ciclo de vida de los objetos o como está deslocalizando

Cuestiones relacionadas