2012-03-06 25 views
5

tengo el siguiente código:NSDictionary AllKeys choques - no pueden entender las circunstancias informe de bloqueo

- (Item *) getRandomItem { 
    if (itemIDs == nil) { 
     [self parse]; 
    } 
    NSArray * allKeys = [allItems allKeys]; 
    int seed = arc4random()%[allKeys count]; 
    return [self getItemByID:[allKeys objectAtIndex:seed]]; 
} 

A veces se estrella en la aplicación en vivo, pero no podemos reproducir el accidente. He intentado analizar el informe y comprender cuál podría ser la causa del accidente, pero no he tenido éxito. Cualquier forma en que intente alterar el objeto allItems para producir un bloqueo, da como resultado un error diferente al que se informa aquí.

me gustaría un poco de ayuda para entender en qué circunstancias se produciría el siguiente choque:

Hardware Model:  iPhone3,1 
Code Type:  ARM (Native) 
Parent Process: launchd [1] 
OS Version:  iPhone OS 5.0.1 (9A405) 
Report Version: 104 
Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x00000010 
Crashed Thread: 0 

Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 
8 CoreFoundation     0x33f85806 +[NSArray arrayWithObjects:count:] 
9 CoreFoundation     0x33fa0e92 -[NSDictionary allKeys] 
10 AClockworkBrain     0x0008f46e -[ItemManager getRandomItem] (ItemManager.m:360) 
...... 

Gracias.

+0

¿Estás usando ARC o no? Esto parece ser un error relacionado con la memoria. –

+1

Espera, ¿estás tratando de agregar un entero sin procesar a tu diccionario? Está intentando enviar un mensaje a un objeto en la memoria 0x10, que parece ser un entero normal en su aplicación. –

+0

Richard, no estamos usando ARC. – dimitrios

Respuesta

9
Thread 0 name: Dispatch queue: com.apple.main-thread 
Thread 0 Crashed: 
0 libobjc.A.dylib     0x3427eb30 _class_isInitialized 
1 libobjc.A.dylib     0x3427e8d6 _class_initialize 
2 libobjc.A.dylib     0x3427e88e prepareForMethodLookup 
3 libobjc.A.dylib     0x3427e76a lookUpMethod 
4 libobjc.A.dylib     0x3427e008 objc_msgSend_uncached 
5 CoreFoundation     0x33f7c020 CFRetain 
6 CoreFoundation     0x33f85bac +[__NSArrayI __new::] 
7 CoreFoundation     0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:] 

Este accidente es la firma de una liberación excesiva o corrupción. Específicamente, una de las claves en su diccionario ha sido liberada o corrupta. En particular, el puntero isa ahora apunta a la basura.

Cuando allKeys intenta crear una matriz temporal de todas las teclas, se trata de retener el objeto dañado (a través de CFRetain, pero tratarlo como una llamada a retain). El tiempo de ejecución no reconoce el puntero isa como una clase inicializada (porque apunta a la basura) e intenta llamar al initialize en esa "clase", lo que lleva al bloqueo.

Ahora, sucede que el isa dañado es probablemente un valor que apunta a un menú legible, pero basura, y que lleva a un colapso de algunas capas de profundidad en el tiempo de ejecución. Más comúnmente, es porque el objeto fue liberado en exceso y luego una estructura resultó ser malloc() 'd en la misma ubicación y esa estructura tiene un puntero como primera entrada, que es un patrón completamente común para las estructuras.

¿Corregir?

Primero, ejecute el analizador y solucione cualquier problema que presente.

A continuación, inspeccione todos los usos de los objetos que son claves en ese diccionario. Vea si puede encontrar dónde puede ocurrir un sobre-lanzamiento.

Por último, intente encender zombies y ver si puede reproducir el bloqueo.

+0

bbum gracias por una respuesta tan detallada. No tengo conocimiento de toda esta información de bajo nivel, pero parece que sí. Estudiaremos esto con cuidado. ¡Gracias de nuevo! – dimitrios

+1

Me ha ocurrido este error porque llamé '[myDict allKeys]' a un hilo diferente al que manejaban los objetos. Como dice esta respuesta, eran punteros para desasignar objetos. – stevel

-2

¿te ayuda si haces esto?

NSArray * allKeys = [NSArray arrayWithArray:[allItems allKeys]]; 
+4

¿Por qué sería útil? – Chuck

+0

No ayudaría. – bbum

+0

No debería haber respondido a toda prisa. Debería haberlo agregado en el comentario, ¡es malo! –

Cuestiones relacionadas