Si usted sigue lo que ahora se considera como la mejor práctica, que debe propiedades de salida de la liberación, ya que debería haberlos retenido en el conjunto de acceso:
@interface MyController : MySuperclass {
Control *uiElement;
}
@property (nonatomic, retain) IBOutlet Control *uiElement;
@end
@implementation MyController
@synthesize uiElement;
- (void)dealloc {
[uiElement release];
[super dealloc];
}
@end
La ventaja de este enfoque es que se hace que la semántica de administración de memoria sea explícita y clara, y funciona de manera consistente en todas las plataformas para todos los archivos nib.
Nota: los siguientes comentarios se aplican solo a iOS antes de 3.0. Con 3.0 y posterior, en su lugar, simplemente debe anular los valores de propiedad en viewDidUnload.
Una consideración aquí, sin embargo, es cuando el controlador podría disponer de su interfaz de usuario y volver a cargar de forma dinámica en la demanda (por ejemplo, si tiene un controlador de vista que carga una vista desde un archivo de punta, pero a petición - decir bajo presión de memoria: lo libera, con la expectativa de que pueda volver a cargarse si la vista es necesaria de nuevo). En esta situación, quiere asegurarse de que cuando se deseche la vista principal, también renuncie a la propiedad de otros puntos de venta para que también puedan desasignarse. Para UIViewController, se puede hacer frente a este problema reemplazando setView:
de la siguiente manera:
- (void)setView:(UIView *)newView {
if (newView == nil) {
self.uiElement = nil;
}
[super setView:aView];
}
Desafortunadamente esto da lugar a un problema aún más.Debido a que UIViewController implementa actualmente su método dealloc
utilizando el método de acceso setView:
(en lugar de simplemente liberar la variable directamente), se llamará en dealloc
, así como en respuesta a una advertencia de memoria ... Esto provocará un bloqueo en dealloc
.
El remedio consiste en asegurar que las variables de salida también están listos para nil
en dealloc
:
- (void)dealloc {
// release outlets and set variables to nil
[anOutlet release], anOutlet = nil;
[super dealloc];
}
Si tenemos una propiedad de retención, no podríamos simplificar esto simplemente diciendo self.uiElement = nil; en todos los lugares que queremos liberar, ya que es una propiedad retener en realidad debería lanzarla correctamente y establecerla en cero sin problemas, una de las ventajas de retener propiedades. –
Normalmente harías 'self.uiElement = nil;' en 'viewDidUnload' no en' setView: '. Y sería más claro simplemente llamar 'self.anOutlet = nil;' en el dealloc. –
No debe llamar a self.anOutlet = nil; en el trato. Es una mala práctica llamar a los usuarios en dealloc. – tobyc