ios memory-management autorelease

ios - Objeto probablemente modificado después de ser liberado



memory-management autorelease (4)

Además de establecer un punto de interrupción en malloc_error_break, presione Comando-6 en xCode para saltar a la pestaña de puntos de interrupción, también habilite las ayudas malloc en su esquema.

Vaya al selector de esquemas, elija "Editar esquema", busque el objetivo "Ejecutar" y vaya a la pestaña "Diagnóstico". Bajo la administración de memoria, habilite garabatos, bordes de protección, objetos malloc y zombie de guardia.

Con un poco de suerte, xCode lo sorprenderá escribiendo fuera de la memoria asignada y corrompiendo la memoria.

Es como la supervisión de un adulto para lidiar con la memoria ...

Estoy trabajando en un proyecto en iPhone. Ahora estoy iniciando un nuevo UIViewController desde otro UIViewController, y luego cambio entre ellos. Aquí está mi código.

iGreenAppDelegate *delegate = [UIApplication sharedApplication].delegate; if(checkInViewController) { [checkInViewController release]; checkInViewController = nil; } checkInViewController = [[CheckInViewController alloc] initWithCheckpoint:checkpoint]; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.8]; [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[delegate window] cache:YES]; [[delegate rootTabBarController].view removeFromSuperview]; [[delegate window] addSubview:checkInViewController.view]; [UIView commitAnimations];

El problema es que la segunda vez que inicio el UIViewController, quiero liberarlo para evitar que se produzca una pérdida de memoria. El depurador muestra

iGreen (916,0x3f60348c) malloc: error para el objeto 0x130350: suma de comprobación incorrecta para el objeto liberado: el objeto probablemente se modificó después de liberarse. establecer un punto de interrupción en malloc_error_break para depurar

Esto es extraño porque los códigos similares en otras partes no devuelven tal error. Además, probé la ejecución automática, pero el programa se bloqueará de inmediato y el Depurador dice que estoy modificando las capas finalizadas.

He estado trabajando en el problema durante toda una noche, y todavía estoy confundido al respecto.


Comprenda el mensaje de error: está diciendo que algo continuó usando (y modificando) el objeto después de que lo liberó. Este código lo libera y no lo modifica a partir de entonces, pero debe preguntarse qué otra cosa podría continuar usándolo (sin saber que ya estaba liberado).

Cada vez que se ejecuta el código de este fragmento de código, libera (libera) cualquier checkinViewController existente, y asigna uno nuevo, y claramente nunca vuelve a tocar el anterior. ¿Pero quién más puede tener un puntero al objeto viejo?

Posiblemente otro código que escribió, y posiblemente [ventana de delegado], que obtiene una referencia a través de "[[ventana de delegado] addSubview: checkInViewController.view];"? Esperemos que este último tome su propia referencia, lo que significa que el lanzamiento no lo liberará de inmediato.

Pero tenga cuidado con cualquier lugar donde esté copiando ese puntero sin agregar una referencia. Si hace esto en algún lugar, y luego en otro lugar (como el fragmento de código anterior) que alguien llama a liberar en el mismo puntero, ahora puede tener un puntero a un objeto que se ha liberado.


Hay un par de cosas que van mal en cuanto a diseño en su código. Primero lance el checkInViewController sin quitar su vista de su supervisión (si hay alguna), luego elimine la vista rootTabBarController de su supervisión, sin hacer nada al controlador, y no agregue el control checkView a la propiedad rootTabBarController o la propiedad rootViewController de la ventana, por lo que está en el aire (solo retenido por su objeto actual). ¿Qué sucede cuando este objeto (actual) se desasigna, pero la vista de checkInViewController permanece en la ventana (retenida por)?

Si libera su checkInViewController pero su vista aún es retenida por la ventana, probablemente creará algunos problemas ...

Sobre el error, creo que en algún lugar hay una referencia débil (no retenida) a su objeto que actúa sobre él una vez que se libera.


Establezca un punto de interrupción en malloc_error_break para depurar.

Hacer eso y publicar el retroceso.

Por lo general, esto significa que corrompió la memoria, pero también puede significar que tiene un objeto sobre lanzado. Intenta construir y analizar, también.