2010-03-05 10 views
47

Este es el código sin modificar de la plantilla de Apple iPhone 'Utilidad de Aplicación':Objective-C - Cuándo utilizar 'auto'

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

MainViewController *aController = [[MainViewController alloc] initWithNibName:@"MainView" bundle:nil]; 
self.mainViewController = aController; 
[aController release]; 

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 
[window addSubview:[mainViewController view]]; 
[window makeKeyAndVisible]; 

} 

Cuando mainViewController se asigna a aController, se especifica la palabra clave self:

self.mainViewController = aController; 

sin embargo, cuando se establece el marco de la mainViewController 's, no se requiere la palabra clave self:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 

Si quito la palabra clave self desde el primer ejemplo, el programa se bloquea con el mensaje:

objc[1296]: FREED(id): message view sent to freed object=0x3b122d0 

Si añado la palabra clave self con el segundo ejemplo, el programa funciona muy bien.

¿Alguien puede explicar por qué self es necesario en el primer caso pero no el segundo? Supongo que en ambos casos mainViewController se refiere a la misma variable de instancia.

+0

Lea las respuestas a esta pregunta: http://stackoverflow.com/questions/2302891/self-instance-var-performance-hit – Felixyz

Respuesta

47

El uso de uno mismo provoca el "setter" de su clase para que se llame a esta variable, en lugar de cambiar el ivar directamente.

self.mainViewController = aController; 

es equivalente a:

[self setMainViewController:aController]; 

Por otro lado:

mainViewController = aController; 

simplemente cambia la variable mainViewController ejemplo, directamente, saltándose cualquier código adicional que pueda ser incorporado en UIApplication de setMainViewController método, como liberar objetos viejos, retener nuevos, actualizar variables internas, etc.

En el caso en que el acceso a la trama, todavía estás llamando a un método de selección:

mainViewController.view.frame = [UIScreen mainScreen].applicationFrame; 

expande a:

[[mainViewController view] setFrame:[[UIScreen mainScreen] applicationFrame]]; 

Idealmente, a prueba de futuro de su código, usted debe también utilice self.mainViewController (o [self mainViewController]) al recuperar este valor también. En general, es mucho menos probable que las clases tengan un código importante en sus métodos "getter" que sus "setters", pero aún es posible que acceder directamente pueda romper algo en una versión futura de Cocoa Touch.

+1

Si está accediendo al ivar directamente desde * dentro de * una clase, no lo hago Veo cómo cualquier actualización futura podría romper eso.Sigue siendo un buen principio utilizar el acceso para evitar complicaciones si necesita refactorizar el código, pero en casos simples, no creo que sea un problema si las clases acceden directamente a sus propios ivars al obtener el valor. Para la configuración, siempre uso el método setter. – Felixyz

+5

Siempre debe usar self, excepto dentro de los métodos getter y setter (si escribe el suyo). De esta forma, la retención de objetos se maneja automáticamente. También puede proporcionar un código personalizado para hacer cosas como validar el iVar o mantenerlo si alguna vez es nulo. Fuera de los métodos getter y setter, raras veces hay alguna buena razón para acceder al iVar directamente. Aunque, muchas personas generalmente lo hacen por error o pereza. – TechZen

+3

Creo que hay al menos otra excepción en la que accedes al ivar directamente: en dealloc. Aparte de eso, supongo que siempre deberías usar self con los getters y setters. –

9

la palabra clave self indica que está utilizando la propiedad getter/setter en lugar de acceder al valor directamente. en caso de que permita que el getter/setter se genere automáticamente utilizando synchronize, debe usar self en el primer ejemplo porque el objeto se retiene allí en lugar de simplemente asignarle un puntero.

+0

Nadie aquí realmente ha explicado lo que es la auto variable Creo que esto fue parte de la pregunta. – Fab1n

+4

self es este puntero similar a C++. Contiene la dirección de clase. – Subrat

Cuestiones relacionadas