AVISO: Cualquier pregunta que no cumpla ninguno de estos criterios podrá ser borrada sin previo aviso.

Error de memoria

Hola,

Ando bastante desesperado con un fragmento de código. El caso es que se me produce un error de memoria de esos repentinos que da a veces. Es es por hacer un duble free (como dice el compilador), es decir, que he hecho un release de mas y cuando la aplicación va a hacer el release se encuentra que este ya esta hecho. He visto la linea de código que produce ese error pero no lo comprendo. El fragmento de código es este:

scroll.clipsToBounds = YES;
scroll.pagingEnabled = NO;
scroll.showsVerticalScrollIndicator = NO;

NSString *path;
UIImage *imagen;
UIButton *button;
Tarjeta *tarjeta;

int i;
CGFloat contentOffset = 10.0f;
for (i = 0; i < [seccion.tarjetas count] ; i++)
{
    tarjeta = [seccion.tarjetas objectAtIndex:i];
    path = [[NSBundle mainBundle] pathForResource:tarjeta.fichero ofType:@"png"];
    imagen = [UIImage imageWithContentsOfFile:path];
    [path release];

    button = [[UIButton alloc] initWithFrame:CGRectMake(0, contentOffset, scroll.frame.size.width, imagen.size.height)];
    [button setImage:imagen forState:UIControlStateNormal];
    [button setImage:imagen forState:UIControlStateSelected];
    [button setImage:imagen forState:UIControlStateHighlighted];
    [button addTarget:self action:@selector(pulsarTarjeta:) forControlEvents:UIControlEventTouchDown];
    button.tag = i;

    [scroll addSubview:button];
    [button release];
    contentOffset = contentOffset + imagen.size.height + 10.0f;

    scroll.contentSize = CGSizeMake(scroll.frame.size.width, contentOffset);
}

La linea que da error es [button release]. Si comment era linea el error no se produce. El case es que no comprendo pro qué debo quitarla. Cuando hago el addsubview del botón la cuenta de referencias pasa a ser de 1 a 2. Cuando ejecuto el release se queda en 1, porque la tiene el scroll, como debe ser, creo.

Al quitar el release la cuenta del botón se queda en 2 con lo que cuando cierre la View ese objeto no se destruiría.

Alguien me puede decir por qué tengo que quitar el release???

preguntado 08 Dic '11, 12:30

MacMux's gravatar image

MacMux
59172233

editó 08 Dic '11, 21:00

Jorge%20S%C3%A1nchez's gravatar image

Jorge Sánchez
917111726


Quizá el error esté en la línia 17 donde liberas un string que ya está autoreleased ([path release]).

enlace permanente

respondido 08 Dic '11, 18:28

Xavier%20Jurado's gravatar image

Xavier Jurado ♦
3.6k2043

Yo creo que no. El método pathForResource de NSBundle es - y no + con lo que, hasta donde creo que se, esos retornos no hacen autorelease.

En cualquier caso, si quito ese release, sigo teniendo el problema.

(08 Dic '11, 18:36) MacMux

El + y el - no tienen absolutamente nada que ver con la gestión de memoria, sólo indican si el método es de clase o de instancia.

La forma en que un método nos devuelve un objeto viene indicada por el verbo del propio método: alloc*, *copy*, new*, *create* (en CoreFoundation) devuelven objetos con retainCount == 1. Cualquier otro método, generalmente, debe retornar un objeto autoreleased. Para más información puedes mirar la documentación de Apple al respecto.

Volviendo a tu problema, no tengo ninguna duda que en la línea 17 hay un error, lo que no quita que pueda haber más en otras partes del código. Revisa los retain/release y activa los zombies para encontrar el culpable.

(08 Dic '11, 19:48) Xavier Jurado ♦

MUCHÍSIMAS GRACIAS.

Tenias razón. Era eso. He leído de nuevo el tema Memory Management y me estaba confundiendo en unos cuantos sitios del programa. Desgraciadamente luego este falla cuando menos lo esperas y yo, personalmente, me vuelvo loco buscando los errores.

Pues eso, muchas gracias Xavier.

(08 Dic '11, 23:27) MacMux

En teoría para casos como este la variable button debería ser autorelease pero no sé mucho de los autorelease.

Tengo un código similar al tuyo. La línea [button release]; la dejé dentro del for y no dio problema.

En mi caso, me llegó a pasar que a la hora de pulsar el botón, la aplicación tronaba con un error EXC_BAD _ACCESS. Lo resolví así:: Creé en el .h un NSMutableArray

NSMutableArray *elementos;

Antes de iniciar el for, inicializaba la propiedad

elementos =[NSMutableArray arrayWithCapacity:[seccion.tarjetas count]];

En el ciclo for, y antes de liberar button

[elementos addObject:button];

Después de salir el ciclo

[elementos retain];

Si tu programa funciona bien, no me hagas caso. este código (según mi deducción) es porque se perdían las referencias de los botones y a la hora de disparar el evento al pulsar, ya no encontraba al bóton en cuestión.

enlace permanente

respondido 08 Dic '11, 20:51

Leonardo%20Molina's gravatar image

Leonardo Molina
8881015

Tu respuesta:
Activar/desactivar vista previa

Sobre esta pregunta

Etiquetas de la pregunta:

×33
×9
×4

Pregunta realizada el: 08 Dic '11, 12:30

Pregunta visitada: 602 veces

Última modificación: 08 Dic '11, 23:27

Seguir esta pregunta

Por Email:

Una vez que entres podrás suscribirte desde aquí para recibir actualizaciones

Por RSS:

Respuestas

Respuestas y Comentarios

Realizar Donación