2012-04-04 42 views
16

Así que estoy depurando una aplicación en preparación para su aplicación para su lanzamiento, y habilité un punto de interrupción universal para "Todas las excepciones". Desde entonces, cada vez que ejecute la aplicación, las impresiones de la consola:Punto de interrupción señalando "objc_autoreleaseNoPool"

Catchpoint 2 (tiro) A la espera de punto de interrupción 1 - "objc_exception_throw" resuelto

objc [11765]: Objeto 0x8f18ff0 de __NSCFLocale clase autoreleased sin piscina en el lugar - acaba de fugas - romper el objc_autoreleaseNoPool() para depurar

objc [11765]: objeto 0x8f190a0 de __NSCFNumber clase autoreleased sin piscina en su lugar - sólo fugas - romper el objc_autoreleaseNoPool() para depurar

objc [11765]: Objeto de la clase 0x8f1fef0 __NSCFLocale autoreleased sin piscina en su lugar - sólo fugas - rotura en objc_autoreleaseNoPool() para depurar

Literalmente impresos 3 veces. No tengo idea de lo que esto significa, pero se ve mal. Cualquier consejo sería apreciado.

+0

¿tiene un grupo de autorrelease? y compruebe si la aplicación tiene fugas con uno de los programas de ayuda que puede encontrar en xcode (perfilarlo) – chikuba

+0

No uso ningún grupo de liberación automática. A decir verdad, no entiendo por qué usarías uno, así que nunca lo hice. Pero intentaré que – Andrew

+0

Aparece antes de la aplicación del. termina, pero comenté línea por línea todo el asunto, y todavía estoy goteando objetos. ¿Cualquier pensamiento? – Andrew

Respuesta

35

Nueva Información

que determina dónde se encuentra mi problema mediante la creación de un método autorelease swizzled.

No recomiendo hacerlo a menos que sepa lo que está haciendo, sin embargo, esto es lo que descubrí.

+ (void) load; //Method is called outside the original autorelease pool. 
+ (void) initialize; // Method is called outside the original autorelease pool. 

NSThread crea su propio subproceso, el método llamado debe incluirse en un grupo de autorrelease.

Grand Central Dispatch se encarga de adaptarse al grupo de autorrelease cuando usa los comandos "dispatch _...". sin embargo, cuando despache manualmente. es posible que desee envolverlo en un grupo de autorrelease.

Además, ARC no se encarga de avisarle que se realizará una liberación automática fuera de un grupo.

Por lo tanto, si usa ARC y sabe que estará fuera del grupo de liberación automática. Y no hay nada que puedas hacer al respecto. Querrá evitar todos los métodos de conveniencia.

usar esto.

[[NSString alloc] initWithFormat:@"%@",myObject]; 

en lugar de esta

[NSString stringWithFormat:@"%@",myObject]; 

Esto permitirá que el sistema de arco para retener y liberar, pero el autorelease subyacente realizado por el método de conveniencia, se omite ya que no se ha utilizado el método de conveniencia.

Espero que ayude.

respuesta original

Ok, no me siento a esta pregunta fue respondida con suficiente detalle.

se presenta el mensaje fue

objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug 

El depurador está señalando un posible punto de interrupción que le ayudará a depurar la situación. Ahora bien, mientras que este punto de interrupción realmente hizo poco para ayudar a depurar la situación. Creo que es importante saber cómo agregar ese punto de interrupción al depurador, así que me dediqué a jugar con él (después de buscar en internet y no encontrar nada) hasta que lo logré.

Es un poco molesto que romper todos los errores no capte esto, pero aquí están los pasos para agregar el punto de interrupción al depurador.

primero que quiere hacer es seleccionar el navegador punto de interrupción del depurador

navigator toolbar

haciendo clic en esta pestaña

breakpoint button

siguiente se mira hacia la parte inferior del panel de navegación y presione el botón Más

Add Exception Breakpoint

Esto le permitirá agregar manualmente un punto de interrupción.

Seleccioné un punto de interrupción C++ e ingresé el nombre del mensaje en el campo de texto del nombre.

Adding custom C++ exception

después de añadir esta excepción se hizo en ruptura hecho.

Sin embargo, esto puede o no ser útil para usted como desarrollador objetivo c. Esto irrumpió en el código de la Asamblea.

assembly code at achieved breakpoint.

Por desgracia, sólo mostró este punto en la pila de llamadas del subproceso.

Thread list

y resultó que el problema se debía a que autorelease una clase llamada autorelease en una llamada dispatch_once. y una investigación más profunda reveló que la carga + (vacía); el método en la clase fue llamado antes que cualquier otra cosa.esto se hace a través de la función call_load_methods y está fuera del hilo en el método principal.

Error Call and Stack

para corregir esto, simplemente añade el envoltorio piscina autorelease alrededor de la llamada.

updated error call

otra solución puede ser la de añadir la piscina autorelease dentro de la carga + (void); método. pero esto fue suficiente para mis usos.

NOTA: Estoy agregando esto a la publicación aquí porque no me gusta encontrar un problema y no ser capaz de encontrar todas las rutas a la respuesta resultante. Si el depurador le dice que agregue un punto de interrupción a la función enumerada, entonces debe haber alguna información en alguna parte para obtener esa información. Con suerte, esto reducirá la frustración de algunos de los que están tratando de encontrar esta respuesta.

+1

Excelente respuesta. Gracias por tomarse el tiempo para armar esta publicación. – Andrew

+1

Lo mismo. Ese punto de ruptura fue de gran ayuda, a pesar de que mi problema terminó siendo completamente diferente. Gracias por tomarse el tiempo. –

+1

FYI, no estoy seguro de si el nombre de la excepción ha cambiado o porque el mío estaba en un archivo objc en lugar de objC++, pero tuve que configurar el punto de interrupción para romper __NSAutoreleaseNoPool en lugar de objc_autoreleaseNoPool. Espero que ayude a alguien en algún momento. La publicación original fue MUY útil sin embargo. – stuckj

1

Muchos de los métodos en la API de cacao devuelven objetos liberados automáticamente. En particular, aquellos métodos que devuelven un objeto que no comienza con init, como [NSNumber numberWithLong:]. Si no tiene un grupo de autorrelease en su lugar, esos objetos se filtrarán. Puede encontrar más información sobre el uso de NSAutoreleasePool en el documentation.

+0

¿Qué significa eso? ¿Qué puedo hacer para solucionar este problema? – Andrew

+0

Gracias. Lo investigaré – Andrew

+0

simplemente ponga uno en el lugar principal donde inicia la aplicación y no tiene que pensar y simplemente usar la belleza que se libera automáticamente objetos :) – chikuba

1

Significa que necesita crear un grupo de autorrelease en el hilo que sucede. De lo contrario, sus objetos asignados no serán destruidos (como lo sugiere el mensaje). Por lo tanto, rompa/pausa en el símbolo, luego suba la pila a la entrada del hilo (o programa) y agregue un grupo de autorrelease. Eso es todo.

+0

Aparece antes de la aplicación del. termina, pero comenté línea por línea todo el asunto, y todavía estoy goteando objetos. ¿Cualquier pensamiento? – Andrew

+0

tiene que agregar un grupo de autorrelease. antes de la ejecución que el punto de ejecución donde se golpea el punto de interrupción. si está en su hilo principal, agregue un grupo de autorrelease a 'int main()' (nota: su plantilla de proyecto probablemente lo haya hecho por usted). de lo contrario, normalmente lo agregarías a la entrada de tu hilo. – justin

Cuestiones relacionadas