2011-06-10 10 views
8

Muchas personas dicen que durante el control de vista viewDidUnload método debe eliminar las subvistas llamando al método removeFromSuperview. Por ejemplo, Three20 hace algo como esto:Dentro de un controlador de vista, ¿es necesario llamar a removeFromSuperview en las subvistas durante viewDidUnload?

- (void)viewDidUnload { 
    [super viewDidUnload]; 
    ... snipped ... 
    [_tableBannerView removeFromSuperview]; 
    TT_RELEASE_SAFELY(_tableBannerView); 
    [_tableOverlayView removeFromSuperview]; 
    TT_RELEASE_SAFELY(_tableOverlayView); 
    ... snipped ... 
} 

entiendo el razonamiento detrás de esta creencia: si se llama a [self.view addSubview:_aView] en loadView, debe llamar [_aView removeFromSuperview] en viewDidUnload. El caso es que esto no parece ser necesario. Cuando se libera la vista de un controlador de vista, su método dealloc libera automáticamente todas sus subvistas. Mi código de prueba muestra subvistas automáticamente se liberan cuando su supervista se libera:

@interface TestView : UIView 
@end 

@implementation TestView 
- (id)retain { 
    NSLog(@"view retain"); 
    return [super retain]; 
} 
- (void)release { 
    NSLog(@"view release"); 
    [super release]; 
} 
- (id)init { 
    NSLog(@"view init"); 
    return (self = [super init]); 
} 
- (void)dealloc { 
    NSLog(@"view dealloc"); 
    [super dealloc]; 
} 
@end 

@interface TestViewController : UINavigationController 
@end 

@implementation TestViewController 
- (void)loadView { 
    NSLog(@"viewController loadView"); 
    [super loadView]; 
    [self.view addSubview:[[TestView new] autorelease]]; 
} 
- (void)viewDidUnload { 
    NSLog(@"viewController viewDidUnload"); 
    [super viewDidUnload]; 
} 
- (void)viewDidAppear:(BOOL)animated { 
    NSLog(@"viewDidAppear"); 
    [super viewDidAppear:animated]; 
    [self dismissModalViewControllerAnimated:YES]; 
} 
- (void)dealloc { 
    NSLog(@"viewController dealloc"); 
    [super dealloc]; 
} 
@end 

El código anterior produce la siguiente salida:

viewController loadView 
view init 
view retain 
view release 
viewDidAppear 
viewController dealloc 
view release 
view dealloc 

Como se puede ver, cuando la vista principal del controlador de vista se libera, sus subvistas también son lanzadas.

Además, el iOS Developer Library [estados] (http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101 -SW4 ): "En el caso de una condición de memoria baja, el comportamiento predeterminado de UIViewController es liberar el objeto de vista almacenado en la propiedad de vista si esa vista no se está utilizando actualmente." Además: "Si usa una propiedad declarada para almacenar una referencia a su vista, y esa propiedad utiliza una semántica de retención, asignarle un valor nil es suficiente para liberar la vista".

Entonces, si al liberar una vista se libera automáticamente su subvista, ¿es realmente necesario llamar al removeFromSuperview durante viewDidUnload?

Respuesta

3

No, no es necesario, el dealloc, como bien dices, hará eso por ti :) (publicación larga, respuesta breve).

1

Lo encontré necesario en mi proyecto. Mi viewController tiene una vista principal (como lo hacen todos) y en este caso se define usando un xib (no asignado programáticamente y agregado como una subvista). Esta vista tiene subvistas con IBOutlets en el controlador de vista. Si, en viewDidUnload, simplemente configuro las propiedades de IBOutlet en nil (self.mySubView = nil), no se llama a dealloc en esa subvista. Si primero lo elimino de su superview (la vista principal), se llama a dealloc.

+1

¿Tiene algún código de ejemplo para ilustrar esto? Como mencionó los XIB, poner el proyecto en Github sería aún más útil. Gracias. –

Cuestiones relacionadas