2008-12-19 14 views
17

Tengo un archivo .xib que contiene una UIView y 2 subvistas de UILabel vinculadas a una clase llamada Nota con las tomas asignadas a cada etiqueta de forma adecuada, la definición de esta clase contiene lo siguiente.¿Debo liberar IBOutlets cuando uso loadNibNamed: method?

@interface Note : UIView { 
    IBOutlet UILabel *time; 
    IBOutlet UILabel *content; 
} 

estoy construyendo esto con el siguiente código

NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"Note" owner:self options:nil]; 
note = [nibViews lastObject]; 
[self addSubview:note]; 

Ahora, en mi nota de fase dealloc clase, no estoy liberando el tiempo o el contenido, pero me pregunto si debería ?

- (void)dealloc { 
    [super dealloc]; 
} 

Asumo no lo hago porque no estoy reteniendo explícitamente estos objetos en cualquier parte de mi código, y no me sintetizar estos en getter/setters. Pero no sé lo suficiente sobre el descifrado de las nib para saber si debería liberarlas en mi fase dealloc o no.

Respuesta

2

Esto es correcto para el iPhone; sin embargo, no sería correcto en Mac.

Sin embargo, es posible que desee volver a trabajar este código. No es seguro suponer que la vista será el último objeto cargado desde el plumín. En su lugar, le sugiero que lo conecte a una toma de "nota" en su controlador de vista o escanee la lista de un objeto que sea una subclase de Nota. (Si está cargando varias Notas y utiliza la opción de salida, simplemente asegúrese de agregar una Nota antes de cargar otra.)

+0

¿Cómo que no puedo garantizar será el último objeto? ¿Quiere decir que es posible ordenar el nivel superior de un plumín en el orden que desee, o que en el momento de la desinstalación, el orden puede cambiarse de lo que aparece en el constructor de interfaz? – seanalltogether

+4

No se garantiza el orden al desarchivar. Por ejemplo, entre iPhone OS 2.1 y 2.2 una sola UITableViewCell coloca en un xib cuando se carga fue devuelto en diferentes posiciones dentro de la matriz (incluso con sólo un único objeto que hay más de un elemento en la matriz devuelta por loadNibNamed). –

-6

I believe you are is correct. Consulte los enlaces de documentación a continuación para obtener más detalles.

Documentación:

+0

la respuesta es incorrecta como se explica en los otros mensajes de este hilo y como se documenta por Apple. – amok

+1

Esta respuesta es correcta para Mac OS X, pero no para iOS. Eche un vistazo a este enlace en "Objetos de nivel superior". http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmNibObjects.html#//apple_ref/doc/uid/TP40004998-SW2 –

0

DEBE liberarlo. Ver

"A medida que reconstruye la jerarquía de objetos, sin embargo, UIKit restablece las conexiones entre los objetos usando el método setValue: forKey, que usa el método setter disponible o conserva el objeto por defecto si no hay un método setter disponible." Nib Object Retention

En otras palabras, como no ha especificado estas entradas como @property (que declara implícitamente un setter), o proporcionó un setter directamente, no hay un método setter disponible, y se aplica la parte final de este párrafo - el objeto se conserva por defecto.

Debe, método en su dealloc(), ajuste todos los IBOutlets a cero usando

self.outletName = nil; 

Si no se define ningún organismo, a continuación, setValue se AutoRelease el valor antiguo (asegúrese de que tiene una NSAutoreleasePool si se ejecuta en un hilo). Si se define un setter, realizará cualquier comportamiento que haya definido. De cualquier manera, el conjunto a cero hará exactamente lo correcto y se asegurará de que no haya pérdidas de memoria. NO HAGA esto

outletName = nil; 

Esto configurará directamente la variable miembro, y omitirá la llamada a setValue.

Consulte la documentación de NSObject setValue: forKey para más detalles.

Ejecución de la herramienta de rendimiento (fugas) no mostrará una fuga, pero se puede comprobar que en realidad hay una fuga mirando el total de ejecución actual de la memoria asignada.

cf The Airsource - Memory Management and NIBs

+0

self.outletName = nil; No, no * no * haz esto; no deberías usar métodos de acceso en dealloc. – mmalc

+0

Re "En otras palabras, porque no ha especificado estas entradas como @property": declarar una propiedad no tiene nada que ver con eso. Es la presencia o ausencia de los usuarios de acceso lo que es importante, no el azúcar sintáctico. – mmalc

+0

De acuerdo y editado. Mi punto era que él no había declarado accesos ni siquiera por el método oculto de hacerlo como @propiedad, pero eso no le salió bien. –

14

Debe liberar una IBOutlet incluso si estás no escritura o síntesis de métodos de acceso. La documentación del ciclo de vida de NIB dice que aunque los objetos no archivados están configurados inicialmente para su liberación automática, el recuento retenido en ellos se incrementa en 1 extra cuando UIKit conecta todos los enlaces de conexión de IBOutlet. Por lo tanto, necesita disminuir manualmente a través de la versión cuando haya terminado.

No es obvio que UIKit estaría haciendo esto por lo que podría suponer que sólo puede salir de los métodos setter/getter apagado y confiar en que todo se autoreleased. Pero ese no es el caso.

en cuenta que Interface Builder Plantillas de liberar explícitamente cualquier IBOutlets, por lo que cualquier agrega deben ser tratados del mismo modo.

0

Usted no será capaz de sacarlos de memoria a menos que declarar la IBOutlets como las propiedades y sintetizarlos a Ivars:

@interface Note : UIView { 
    IBOutlet UILabel *time; 
    IBOutlet UILabel *content; 
} 

@property (nonatomic, retain) IBOutlet UILabel *time; 
@property (nonatomic, retain) IBOutlet UILabel *content; 

@end 


@implementation Note 
@synthesize time, content; 

// your methods 

- (void)dealloc { 
    [time release], time = nil; 
    [content release], content = nil; 
    [super dealloc]; 
} 

@end 
Cuestiones relacionadas