2011-03-18 28 views
5

He mirado en el proyecto "PageControl" muestra de Apple (See here) y veo esta función en el código:¿Código incorrecto en el código de ejemplo de Apple?

- (void)loadScrollViewWithPage:(int)page 
{ 
    if (page < 0) 
     return; 
    if (page >= kNumberOfPages) 
     return; 

    // replace the placeholder if necessary 
    MyViewController *controller = [viewControllers objectAtIndex:page]; 
    if ((NSNull *)controller == [NSNull null]) 
    { 
     controller = [[MyViewController alloc] initWithPageNumber:page]; 
     [viewControllers replaceObjectAtIndex:page withObject:controller]; 
     [controller release]; 
    } 

    // add the controller's view to the scroll view 
    if (controller.view.superview == nil) 
    { 
     CGRect frame = scrollView.frame; 
     frame.origin.x = frame.size.width * page; 
     frame.origin.y = 0; 
     controller.view.frame = frame; 
     [scrollView addSubview:controller.view]; 

     NSDictionary *numberItem = [self.contentList objectAtIndex:page]; 
     controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]]; 
     controller.numberTitle.text = [numberItem valueForKey:NameKey]; 
    } 
} 

Hay algo que no entiendo.
Si la pieza de prueba if ((NSNull *)controller == [NSNull null]) es cierto, entonces tenemos

controller = [[MyViewController alloc] initWithPageNumber:page]; 
[viewControllers replaceObjectAtIndex:page withObject:controller]; 
[controller release]; 

A continuación, sólo después de:

if (controller.view.superview == nil) 

Pero, controlador acaba de ser puesto en libertad. Creo que puede funcionar porque el controlador todavía está en la memoria, pero ¿no es esta una forma incorrecta de codificar el material?

Respuesta

2

Cuando se agregó el objeto controller en viewControllers que retuvo el objeto. Por lo tanto, sigue siendo un objeto vivo después de que lo liberan.

¿Está mal? Tal vez, requiere conocimiento de lo que NSArray hace, pero eso es bastante común.

que lo habría hecho así:

if ((NSNull *)controller == [NSNull null]) 
{ 
    controller = [[[MyViewController alloc] initWithPageNumber:page] autorelease]; 
    [viewControllers replaceObjectAtIndex:page withObject:controller]; 
    controller = [viewControllers objectAtIndex:page]; 
} 
+0

+1 a la idea de usar la liberación automática. Tal como están las cosas, el código no solo se basa en el hecho de que NSArray retiene los objetos agregados (bastante común, como usted dice), sino que tampoco depende de ningún otro hilo que elimine el objeto del NSArray. (Es cierto que, dado que estos son objetos de UI, es poco probable que suceda, pero sigue siendo un mal karma seguir usando un objeto que no conservas). –

3

Creo que tienes razón. Si estuviera codificando esto, habría agregado:

if ((NSNull *)controller == [NSNull null]) 
{ 
    controller = [[MyViewController alloc] initWithPageNumber:page]; 
    [viewControllers replaceObjectAtIndex:page withObject:controller]; 
    [controller release]; 
    controller = [viewControllers objectAtIndex:page]; 
} 

Para obtener una referencia después de la liberación.

O supongo que a la inversa sería utilizar la liberación automática en lugar de soltar.

+0

¿Puedo tener una explicación para la downvote, por favor? –

+0

@fluchtpunkt: No entiendo el motivo de este rechazo ... Esta respuesta parece ser válida ... – Oliver

Cuestiones relacionadas