2010-01-25 11 views
11

Sé que las discusiones sobre los estilos de codificación tienden a terminar en desastres e interminables guerras de llama, pero eso no es lo que quiero llegar. Durante la última década, principalmente vi dos estilos de codificación diferentes para los métodos dealloc en Objective-C. El primero y el más común era colocar dealloc en la parte inferior del archivo. Este es también el estilo que usa Apple en las plantillas predeterminadas de Xcode. La lógica detrás de esto parece ser que dealloc se invoca cuando se acerca el final del objeto, por lo que el final del archivo parece ser una buena metáfora. Por otro lado, un par de personas tiende a poner dealloc directamente debajo de las directivas @synthesize. Esto tiene dos desventajas importantes en mi opinión:¿Cuál es su estilo de codificación preferido para dealloc en Objective-C?

  1. La parte superior del archivo se llena de aburrido código.
  2. Es más difícil encontrar las partes esenciales en su clase, tiene que desplazarse hacia abajo.

La gran ventaja en mi opinión es que usted tiene una conexión visual directa entre las propiedades y el mensaje correspondiente release.

La otra cosa es niling las variables ya publicadas. Si bien no creo que esto sea necesario, especialmente en el contexto de objetos donde la variable completa se desciende después de que termina el dealloc, tiendo a nulificar las variables. Estoy acostumbrado a hacer esto para las variables en el alcance de la función, por lo que soy coherente con mi estilo de codificación.

Esta es la forma en la mayoría de mis clases se parecen:

@implementation Bar 

@synthesize foo; 

- (void)dealloc 
{ 
    [foo release], foo = nil; 

    [super dealloc]; 
} 

// Initializers and other methods… 

ya he mencionado un par de pros y contras. ¿Qué opinas sobre este tema? ¿Cuál es el estilo de codificación que usa en dealloc y por qué? ¿Hay otros pros y contras que olvidé mencionar?

No quiero comenzar una guerra de llamas aquí. Solo quiero saber qué estilo usas y si tienes razones específicas para esto o si esto no te importa al final.

+0

Eventho no desea que las personas comiencen discusiones y llamas, sucederá a preguntas como esta. – Younes

Respuesta

16

Me gusta poner la implementación dealloc justo debajo de los inicializadores. De esa manera, cuando agrego una nueva variable de instancia, recuerdo release justo después de I init.

Además, me parece realmente útil utilizar la directiva #pragma mark para que sea más fácil navegar por el archivo. Entonces "agrupo" los métodos init y dealloc juntos bajo un encabezado llamado "inicializadores". Al explorar el archivo, tener esos títulos hace que sea mucho más fácil encontrar lo que está buscando sin distraerse con el método dealloc.

Podría ser un código aburrido, pero es importante.

+0

Envuelvo el inicializador (s) + dealloc en un #pragma mark - Ciclo de vida de los objetos (similar al "Ver ciclo de vida" de las plantillas de Apple para UIViewController) –

5

Pongo mi dealloc en la parte superior, justo debajo de las directivas @synthesize. Es un código un poco torpe y aburrido, pero un código tan importante, por lo que obtiene la mejor facturación. Además, poder comparar las propiedades y las liberaciones es vital.

-1
- (id)init{ 
    self = [super init]; 
    if(self) { 
     someVar = [[NSMutableArray alloc] init]; 
     // something like the following shouldn't be released: 
     someString = [NSString stringWithFormat:@"ANumber: %d",10]; 
    } 
    return self; 

    - (void)dealloc{ 
     [someVar release]; someVar = nil; 
     [super dealloc]; 
    } 

esa es la manera de hacerlo :)

+4

Estoy bastante seguro de que stringWithFormat devuelve un objeto liberado automáticamente. Debes retenerlo en init y liberarlo en dealloc. Además, sus llaves no balancean ... – walkytalky

+0

lea por favor, algo como el siguiente no debería ser publicado como lo indico en mi comentario en el código, lo que quise decir con eso es que el objeto que estoy usando allí se autorrellena. –

+0

Enviar mensajes a self inside dealloc es, al menos, una muy mala práctica. –

10

no ponga sus Ivar a cero en dealloc si usted no tiene una razón específica para. No sirve para nada y, en el mejor de los casos, enmascara los errores del programador que sería mejor averiguar que ocultarse.

+1

+1: Al no establecer las variables de instancia en 'nil' y usar el buen ol' 'NSZombieEnabled', he detectado algunos errores lógicos a lo largo de los años que nunca habría encontrado de otra manera. – Alex

3

Lo puse en la parte inferior. Esto me permite simplemente golpear el extremo e ir a él cuando agrego algo que necesita desasignación. Tampoco lo quiero alrededor de mis sintetizadores de propiedades, porque esto es engañoso. No todo lo que trato tiene necesariamente un acceso sintetizado adjunto. Diablos, ni siquiera está necesariamente todo en el inicializador. Si trato de usar un atajo de esa manera, es probable que lo arruine.

+1

De acuerdo. Me refiero a todas las variables miembro en '@ interface' cuando estoy escribiendo' dealloc'. –

+0

Además, finalmente pude definir el bloque ivar en las rocas de implementación @ (pero sigo saltando al encabezado y viceversa). –

8

Mi pedido:

  1. síntesis y @dynamic directivas (que empecé a hacer esto en la parte superior en algún momento de 2011; anteriormente, estaban en las implementaciones de descriptor de acceso)
  2. Los métodos de clase (+load, +initialize, +sharedFoo, otros)
  3. inicializadores
  4. dealloc
  5. finalize
  6. implementaciones de descriptor de acceso de encargo
  7. métodos de conformidad
  8. Protocolo, agrupados por protocolo (por lo general con #pragma mark directivas)
  9. métodos de controlador de notificación (normalmente declaradas en una extensión de la clase en la parte superior)
  10. otros métodos (por lo general declarados en una extensión de la clase en la parte superior)

Dentro del método dealloc:

  • No utilice mensajes de acceso, implícitos (acceso a propiedades) o explícitos. Cualquier acceso personalizado impuro puede no ser seguro para invocar un objeto parcialmente desasignado. (Lo mismo ocurre con los inicializadores.)
  • No configure ivars en nil. El objeto está parcialmente desasignado; ¿Por qué todavía estás enviando mensajes? (Si no lo está, entonces nada está mirando los valores de los ivars.
  • (Si fuera de alguna manera apropiado establecer ivars en nil) No abuse del operador de coma. Una expresión como [foo release], foo = nil mezcla los tipos (primero void de la expresión del mensaje, luego id de la expresión de asignación). Estas son declaraciones separadas; escríbelos como tales.

  • [super dealloc] es siempre el último y siempre tiene una línea vacía encima, enfatizando su presencia.

Por supuesto, también tengo activado "Advertencias de trato como errores", así que si olvido [super dealloc], rompo mi compilación.

+1

Estos son muchos buenos consejos para mejorar el estilo de codificación de Objective-C. Gracias por compartirlos. Sé que no tiene sentido configurar los punteros a 'nil' después de soltarlos en' dealloc'. Simplemente lo hago, porque estoy acostumbrado a hacerlo en un contexto de método. También uso una línea en blanco sobre '[super dealloc]' para enfatizar la importancia. Una cosa interesante es que sintetizas tus propiedades entre los métodos. ¿Tienes una razón específica para esto? –

+1

Es un artefacto histórico: antes de las propiedades, todos los descriptores de acceso eran personalizados, y no siempre los declaraba en el encabezado. Por lo tanto, la definición sería la primera que el compilador oyera de ellos, por lo que no podría usarlos antes o el compilador se quejaría con razón al respecto. Por lo tanto, estos usuarios de acceso no declarados deben definirse antes de cualquier cosa que pueda usarlos. Ahora sintetizo casi todos mis accesorios, pero mi elección de ubicación sigue viva. –

+0

Hoy en día, sintetizo en la parte superior de la implementación, justo debajo de cualquier variable de instancia explícita. De esta forma, todas las variables de instancia, explícitas y sintetizadas, están juntas y disponibles en toda la clase, incluso en los inicializadores y 'dealloc'. –

Cuestiones relacionadas