Explicación detallada de la esencia de iOS EXC_BAD_ACCESS y la depuración del modo zombie

Enlace original

Comprensión simple de EXC_BAD_ACCESS

Cuando encuentra un bloqueo causado por EXC_BAD_ACCESS, significa que envía un mensaje a un objeto liberado. Ésta es la situación más común.

La esencia de EXC_BAD_ACCESS

En C y Objective-C, ha estado lidiando con punteros. Un puntero no es más que una variable que almacena la dirección de memoria de otra variable. Cuando envíe un mensaje a un objeto, se hará referencia al puntero a ese objeto. Esto significa que obtiene la dirección de memoria a la que apunta el puntero y accede al valor en esa área de almacenamiento.

Cuando el área de memoria ya no está asignada a su aplicación, o en otras palabras, el área de memoria no se usa cuando cree que se usa, el área de memoria es inaccesible. En este momento, el kernel lanzará una excepción (EXC), lo que indica que su aplicación no puede acceder al área de memoria (BAD ACCESS).

En resumen, cuando se encuentra con EXC_BAD_ACCESS, significa que el bloque de memoria al que está intentando enviar un mensaje, pero el bloque de memoria no puede ejecutar el mensaje. Sin embargo, en algunos casos, EXC_BAD_ACCESS es causado por un puntero dañado. Siempre que su aplicación intente hacer referencia a un puntero dañado, el kernel lanzará una excepción.

Tres puntos de instrucciones de depuración EXC_BAD_ACCESS

1. La depuración de EXC_BAD_ACCESS puede ser muy complicada y frustrante.
2. Lo que necesita saber es que su aplicación no es necesariamente inaccesible al área de memoria en el momento del bloqueo. Por eso a menudo es difícil depurar EXC_BAD_ACCESS.
3. Lo mismo ocurre con los punteros dañados. Cuando su puntero está dañado, su aplicación no se bloqueará. Al mismo tiempo, si pasa un puntero dañado hacia adelante y hacia atrás en la aplicación, no se bloqueará. Cuando una aplicación intenta hacer referencia a un puntero dañado, se bloquea.

EXC_BAD_ACCESS debugging-zombie debugging mode

En Xcode, puede habilitar objetos zombies, lo que significa que los objetos liberados se conservarán como zombis. En otras palabras, mantener los objetos liberados es para depurar. Aquí no hay magia involucrada. Si envía un mensaje a un objeto zombi, su aplicación se bloqueará debido a EXC_BAD_ACCESS.

¿Esto es bueno? Lo que hace que EXC_BAD_ACCESS sea difícil de depurar es que no sabe a qué objeto intenta acceder su aplicación. Los objetos zombis resuelven este problema en muchos casos. Al retener los objetos liberados, Xcode puede decirle a qué objeto está intentando acceder, lo que facilita mucho la búsqueda de la causa del problema.

Operación específica del modo de depuración zombie

Habilitar objetos zombies en Xcode es muy fácil. Haga clic en Editar esquema en la esquina superior izquierda y seleccione Editar esquema. Seleccione Ejecutar a la izquierda y abra la opción Diagnóstico en la parte superior. Para habilitar objetos zombies, marque la casilla Objetos zombies.

Modo de depuración zombi

Si encuentra EXC_BAD_ACCESS ahora, imprímalo en la consola de Xcode para indicarle dónde encontrar el problema. Eche un vistazo a la salida de ejemplo a continuación.

  -[CLTextView textInputView]: message sent to deallocated instance 0x7acb0200

En el ejemplo anterior, Xcode nos dice que el mensaje de textInputView: se envía a un objeto zombie. Sin embargo, el objeto zombie ya no es una instancia de la clase CLTextView. El área de memoria previamente asignada a la instancia de CLTextView ya no se asigna a su aplicación. Esto proporciona una buena sugerencia para que comprenda la causa raíz del problema. Desafortunadamente, el objeto zombie no podrá guardar el registro EXC_BAD_ACCESS para cada falla de su día. Dado que el objeto zombie no tiene estos métodos, puede utilizar otros métodos para realizar un análisis adecuado.
El motivo del objeto zombie en el ejemplo anterior: al escribir la categoría UITextView, se agregó una notificación denominada UITextViewTextDidChangeNotification, que se publicó en el siguiente código después de su uso, lo que provocó un error.

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UITextViewTextDidChangeNotification
                                                  object:self];
}

Xcode analiza el proyecto (si el objeto zombie no puede resolver su problema)

Para usar Xcode para analizar su proyecto, seleccione Analizar en el menú Producto de Xcode o presione Shift-Comando-B. Xcode tomará un momento, pero cuando se complete verá una lista de problemas en el Navegador de problemas a la izquierda. Los problemas encontrados por Analizar se resaltan en azul.

Análisis de Xcode

Cuando haces clic en una pregunta, Xcode señalará el bloque de código de la pregunta, que es exactamente a lo que debes prestar atención. Tenga en cuenta que Xcode es solo una recomendación. En algunos casos, esto es posible y el problema es irrelevante y no se ha solucionado. Si no puede encontrar el error que causó EXC_BAD_ACCESS, debe examinar cuidadosamente el proyecto Xcode y analizar todos los problemas encontrados en él.

Supongo que te gusta

Origin blog.csdn.net/Draven__/article/details/90575578
Recomendado
Clasificación