2010-06-17 20 views
20

sólo estaba haciendo una revisión de código y comenzó a preguntarse:si (auto = [súper init]) vs. if ((auto = [súper init]))

pensé if (self = [super init]) comprueba si la asignación de valor de retorno de [super init] a la variable self tuvo éxito o no (valor de operación). Por lo tanto, (self = nil) sería realmente TRUE.

pensé if ((self = [super init])) cheques cuál es el valor de self después de la asignación (valor de la variable). Por lo tanto, ((self = nil)) sería FALSE.

¿Cuál es la forma correcta de utilizar para inicializar sus propias clases? La documentación de Apple usa la anterior (for example here), que estilo estoy usando ahora.

Respuesta

18

Ambos hacen lo mismo. Lo que el if evalúa es el valor de la expresión dentro de él, que es el valor asignado en una asignación. Por lo tanto, cuando self no sea nulo, procederá al bloque if.

La segunda forma de lanza parens alrededor de ella para silenciar las advertencias del compilador potenciales acerca de las asignaciones dentro de los condicionales, que generalmente es una mala práctica y posiblemente un error tipográfico. Pero esto es idiomático Objective-C, así que está bien hacerlo de la primera manera.

+0

Gracias por aclarar lo que hace la expresión, ¡y por qué pensé que tenía que haber paréntesis adicionales! Ahora recuerdo tener tales advertencias de compilador en otros entornos y agregar segundos paréntesis (después de comprobar que la expresión realmente hizo lo que quería, por supuesto). – JOM

4

"Una expresión de asignación tiene el valor del operando izquierdo después de la asignación" (C99), por lo que de cualquier forma tiene el valor de la variable, como lo pones. Los paréntesis adicionales no hacen diferencia (excepto posiblemente para advertencias).

12

Como otros han dicho que los paréntesis no son importantes en este caso. Donde hacen la materia es si marca explícitamente en contra nula:

if (self = [super init] != nil) // wrong! 

if ((self = [super init]) != nil) // right 

= tiene mayor precedencia que = por lo que en el primer caso se asigna el resultado booleano de [super init] != nil (probablemente cierto) a uno mismo y luego hace la prueba para el si.

Personalmente, no me importa, ya sea, pero prefiero hacer la asignación explícitamente fuera de la prueba. Esto es un reflejo de mi experiencia en programación que me ha llevado a la creencia de que los booleanos son un tipo diferente de enteros y punteros y que las asignaciones no son expresiones, aunque, en el caso de la implementación C, estoy equivocado.

self = [super init]; 
if (self != nil) 
+0

¡Buen recordatorio sobre la precedencia! – JOM