Pregunta

Si tengo algo como un UILabel vinculado a un archivo xib, ¿debo liberarlo en el acuerdo de mi vista?La razón por la que pregunto es porque no lo asigno, lo que me hace pensar que tampoco necesito liberarlo.por ejemplo (en el encabezado):

IBOutlet UILabel *lblExample;

en la implementación:

....
[lblExample setText:@"whatever"];
....

-(void)dealloc{
    [lblExample release];//?????????
}
¿Fue útil?

Solución

Si sigue lo que ahora se considera la mejor práctica, podrá debería libere las propiedades de salida, porque debería haberlas conservado en el descriptor de acceso set:

@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 hace que la semántica de gestión de la 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 sólo a iOS anteriores a 3.0.Con 3.0 y versiones posteriores, simplemente debería anular los valores de propiedad en viewDidUnload.

Sin embargo, una consideración aquí es cuándo su controlador podría deshacerse de su interfaz de usuario y recargarla dinámicamente según demanda (por ejemplo, si tiene un controlador de vista que carga una vista desde un archivo nib, pero a pedido, digamos bajo presión de memoria). -- lo libera, con la expectativa de que pueda recargarse si la vista es necesaria nuevamente).En esta situación, desea asegurarse de que, cuando se elimine la vista principal, también renuncie a la propiedad de cualquier otro punto de venta para que también se pueda desasignar.Para UIViewController, puede solucionar este problema anulando setView: como sigue:

- (void)setView:(UIView *)newView {
    if (newView == nil) {
        self.uiElement = nil;
    }
    [super setView:aView];
}

Desgraciadamente esto da lugar a otra cuestión.Debido a que UIViewController actualmente implementa su dealloc método usando el setView: método de acceso (en lugar de simplemente liberar la variable directamente), self.anOutlet = nil será llamado dealloc así como en respuesta a una advertencia de memoria...Esto provocará un colapso en dealloc.

La solución es garantizar que las variables de salida también se establezcan en nil en dealloc:

- (void)dealloc {
    // release outlets and set variables to nil
    [anOutlet release], anOutlet = nil;
    [super dealloc];
}

Otros consejos

Encontré lo que estaba buscando en los documentos de Apple.En resumen, puedes configurar tus objetos como propiedades que liberas y retienes (o simplemente @property, @synthesize), pero no es necesario para cosas como UILabels:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/10000051i-CH4-SW18

El

[anOutlet release], anOutlet = nil;

La parte es completamente superflua si has escrito setView:correctamente.

Si no lo libera en Dealloc, aumentará la huella de memoria.

Vea más detalles aquí con el instrumento gráfico ObjectAlloc

En cierto sentido, la etiqueta se asigna creándola en IB.

Lo que hace IB es observar sus IBOutlets y cómo se definen.Si tiene una variable de clase a la que IB debe asignar una referencia a algún objeto, IB enviará un mensaje de retención a ese objeto por usted.

Si está utilizando propiedades, IB hará uso de la propiedad que tiene para establecer el valor y no retener explícitamente el valor.Por lo tanto, normalmente marcarías las propiedades de IBOutlet como retenidas:

@property (nonatomic, retain) UILabel *lblExample;

Por lo tanto, en otros casos (usando propiedades o no), debe llamar a la liberación en su acuerdo.

No es necesario liberar cualquier IBOutlet que sea una subvista de la vista principal de Nib, porque se le enviará el mensaje de liberación automática al crear el objeto.Los únicos IBOutlet que necesita liberar en su acuerdo son objetos de nivel superior como controladores u otros NSObject.Todo esto se menciona en el documento de Apple vinculado anteriormente.

Si no configura IBOutlet como una propiedad sino simplemente como una variable de instancia, aún así debe liberarlo.Esto se debe a que al initWithNib, se asignará memoria para todos los IBOutlets.Entonces, este es uno de los casos especiales que debe liberar aunque no haya retenido ni asignado memoria en el código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top