2011-06-11 16 views
16

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.Objeto probablemente fue modificado después de ser liberado

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 la segunda vez que inicio la UIViewController, quiero soltarlo para evitar causar pérdida de memoria. El depurador muestra

iGreen malloc (916,0x3f60348c): error para el objeto 0x130350: Suma de comprobación incorrecta para objeto liberado - objeto probablemente se modificó después de ser liberado. 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 dicho error. Además, probé la liberación automática, pero el programa se bloqueará inmediatamente 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.

+0

Por cierto, si no me libero al viewcontroller, el programa funciona bien, pero no creo que sea una buena manera de solucionarla. ¿Alguien me puede ayudar a encontrar el problema? – Stone

+0

Es difícil seguir lo que está sucediendo en su código solo con este fragmento, pero generalmente solo necesita asignar el controlador de vista, agregarlo a su controlador tabbar y luego liberar el controlador de vista. El controlador tabbar retiene el controlador de vista por lo que se mantendrá. Me parece que lo estás liberando antes de que el controlador tabbar termine con él. ¿Tal vez puedas agregar más código a esta pregunta para mayor claridad? –

+0

puede agregar su implementación initWithCheckpoint? Además, ¿ha intentado construir y analizar en Xcode Menu? – AmineG

Respuesta

18

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

Haz eso y publica la traza inversa.

Por lo general, esto significa que corrompió la memoria, pero también puede significar que tiene un objeto liberado en exceso. Prueba Build and Analyze, también.

+8

¿Y cómo puedo hacer eso? ¿Cómo configuro un punto de interrupción en malloc_error_break? –

+34

@ JCLeitão Ejecutar> Puntos de interrupción> Agregar punto de corte simbólico> luego poner "malloc_error_break" – geekazoid

+2

@geekazoid, gracias, creo que esto ayudará a los demás también ... :) –

3

Comprender el mensaje de error: es decir que algo continuó usando (y modificando) el objeto después de liberarlo. Este código lo libera y no lo modifica a partir de entonces, pero tiene que preguntar qué más podría continuar usándolo (sin saber que ya fue liberado).

Cada vez que se ejecuta el código en este fragmento, 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 [delegar ventana], que obtiene una referencia a través de "[[delegar ventana] addSubview: checkInViewController.view];"? Esperemos que este último tome su propia referencia, lo que significa que la liberación no lo liberará de inmediato.

Pero ten cuidado con cualquier lugar donde estés copiando ese puntero sin agregar una referencia. Si haces esto en algún lugar, y luego en otro lugar (como el fragmento de arriba) alguien llama a liberar en el mismo puntero, ahora puede tener un puntero a un objeto que ha sido liberado.

1

Hay un par de cosas que van mal con el diseño en su código. Primero libere el checkInViewController sin quitar su vista de su supervista (si corresponde), luego quite la vista de rootTabBarController de su superview, sin hacerle nada al controlador, y no agregue checkInViewController al rootTabBarController o la propiedad rootViewController de la ventana, por lo que está en el aire (simplemente retenido por su objeto actual). ¿Qué sucede cuando este objeto (actual) se desasigna, pero la vista de checkInViewController se mantiene (retenida por) en la ventana?

Si se quita el checkInViewController pero su punto de vista todavía es retenido por la ventana, que es probablemente va a crear algunos problemas ...

Sobre el error, creo que hay alguna parte una referencia débil (no retenido) a su objeto que actúa sobre él después de ser liberado.

9

Además de establecer un punto de interrupción en malloc_error_break - presione Command-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", encuentre el objetivo "Ejecutar" y vaya a la pestaña "Diagnóstico". Debajo de la administración de memoria, se habilitan los objetos de garabatos, bordes de protección, guardia malloc y zombie.

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

Es como supervisión de un adulto para hacer frente a la memoria ...

+0

Elimina el rendimiento, espero que aún valga la pena. Probando ... :) – Narek

+0

El rendimiento de la muerte, mientras se depura, para encontrar un error me parece bien. –

Cuestiones relacionadas