2009-10-07 13 views
26

¿Tienes que liberar IBOulets en dealloc? No estoy seguro de esto porque no hice el alloc y normalmente solo lanzas para algo que llamas alloc. ¿Nadie sabe?¿Tienes que liberar IBOulets en dealloc?

+0

Duplicado: http://stackoverflow.com/questions/61838/do-i-need-to-release-xib-resources – Casebash

Respuesta

35

Sus IBOutlets son probablemente @properties. Si lo son, y usted tiene retain como un atributo, entonces sí es necesario que el lanzamiento en -dealloc

En otras palabras:

@interface MyViewController : UIViewController { 
    IBOutlet UITableView *myTable; 
} 

@property (nonatomic, retain) IBOutlet UITableView *myTable; 

@end 

Tendrá que [myTable release]; en su dealloc.

Si realiza una nueva aplicación de navegación basada en Xcode, y mira en el appdelegate.h:

@interface Untitled1AppDelegate : NSObject <UIApplicationDelegate> { 

    UIWindow *window; 
    UINavigationController *navigationController; 
} 

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; 

@end 

y la dealloc para appdelegate.m:

- (void)dealloc { 
    [navigationController release]; 
    [window release]; 
    [super dealloc]; 
} 

La clave para ver Aquí hay líneas como estas:

@property (nonatomic, retain) IBOutlet UIWindow *window; 

Si hay una retención allí, eso significa que la propiedad está siendo " propiedad de su código y debe liberarlo.

Por supuesto, hay otras formas, como no declarar las IBOutlets como propiedades, o declararlas como propiedades sin retener. Encuentro que en la mayoría de los casos prefiero que se conserven las propiedades, que luego tengo que liberar explícitamente. Un ejemplo de esto es cuando cambias de un controlador de vista a otro. Cuando un controlador de vista se descarta, sus vistas se eliminan y se liberan. Cualquier IBOutlet UILabels en esa vista se liberaría también si no los retuviera. Eso significa que cuando vuelvo a la vista anterior, tengo que revisar y restablecer mis etiquetas y controles a sus últimos valores, cuando podría haberlos guardado fácilmente si solo conservo IBOutlet.

2

Como dijiste, debes liberar todo lo que te asignaste (con alloc o copy). Funciona de la otra manera: no debe liberar ningún objeto Cocoa que no haya asignado (algunas funciones de CoreFoundation se asignan, y usted es responsable de liberarlas, pero no es el caso aquí).

Si no asignó su IBOutlet, no tiene que soltarlo, a menos, por supuesto, por alguna razón, lo retuvo en algún lugar.

+1

La frase clave es ("a menos que lo hayas reencuado en alguna parte") lo que sucederá si use hacer una propiedad (no atómica, retener). – Fraggle

8

No se trata de IBOutlet, se trata de su declaración. Si utiliza un nuevo asistente de proyecto en Xcode, probablemente obtenga un código como este en su archivo de encabezado.

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController; 

Se puede ver, hay conservan palabra clave en el archivo de cabecera. Siguiendo la guía de gestión de memoria, DEBE liberar todo lo que retiene (llamando a alloc, copy, retener, etc.). Y tiene conservar en su código, entonces debe liberar.

Además, el asistente ya agrega un código de versión para usted.

- (void)dealloc { 
    [tabBarController release]; 
    [window release]; 
    [super dealloc]; 
} 
9

Si sólo utiliza IBOutlet en su interfaz, NO es necesario para liberarlos. La razón de ser es que a menos que los retenga explícitamente en su código, simplemente están siendo establecidos. Se quedan porque la vista está allí. Obviamente, si también usas propiedades y las conservas, debes liberarlas en dealloc.

+0

¿No está esta respuesta en conflicto con la anterior? ¿Necesitas o no? Muy confundido. – erotsppa

+0

No, no está en conflicto: "Obviamente, si también utiliza propiedades y las conserva, debe liberar en dealloc". – mahboudz

+0

Como prueba, crea una nueva aplicación basada en Nav en Xcode. Verá cómo liberan IBOutlets en su dealloc. – mahboudz

1

Esto es lo que he estado haciendo con respecto a IBOutlet objetos (en combinación con un archivo NIB):

@interface MyViewController : UIViewController { 
    UILabel *label; 
} 

@property (nonatomic, retain) IBOutlet UILabel *label; 

@end 

@implementation MyViewController 
@synthesize label; 

- (void)setView:(UIView *)aView { 
    if (!aView) { 
    // view is being set to nil 
    // set outlets to nil to get the benefit of the didReceiveMemoryWarning! 
    self.label = nil; 
    } 
    // Invoke super's implementation last 
    [super setView:aView]; 
} 

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

- (void)viewDidUnload { 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
    self.label = nil; 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

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

lateral pregunta: ¿Tiene más sentido usar self.label = nil en dealloc, o debe release, de manera expresa llamado (por ejemplo, para mantener feliz el analizador estático)?

supongo que, en ese momento, estamos en nuestro camino fuera de todos modos, así que no hay necesidad de ajustar nuestros objetos IBOutlet a cero.

1

Si esta es tu BlahViewController.h:

// BlahViewController.h 
#import <UIKit/UIKit.h> 
@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
} 
@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar; 

@end 

entonces esto sería su dealloc en BlahViewController.m:

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

Sin embargo, si este es su BlahViewController.h:

// BlahViewController.h 
#import <UIKit/UIKit.h> 
@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
} 

@end 

entonces esto sería su dealloc en BlahViewC ontroller.m:

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

Y, por último, si este es su BlahViewController.h:

// BlahViewController.h 
#import <UIKit/UIKit.h> 

@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
    IBOutlet MKMapView *map; 
} 

@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar; 

@end 

entonces esto sería su dealloc en BlahViewController.m:

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

En resumen, si lo declaras como propiedad, con retain, entonces necesitas liberarlo.

2

Para responder a la pregunta de lado a Joe D'Andrea. Puede usar self.label = nil;. Debido a que está llamando setLabel, que se genera automático:

- (void)setLabel:(UILabel *)input 
{ 
    [label autorelease]; 
    label = [input retain]; 
} 

Como se puede ver la corriente label se dará a conocer a continuación nil se asigna a la etiqueta.

Pero asegúrese de que usted no escribe como label = nil. Eso no funcionará. Porque necesita llamar al método de acceso de etiqueta generado automáticamente.

Cuestiones relacionadas