2011-07-12 10 views
14

Estoy mirando las diferencias presentadas a un proyecto por otro desarrollador, y tienen un montón de código que hace !!<some BOOL value>. De hecho, este parece ser su patrón estándar para implementar getters y setters booleanos. Han implementaron su código como:Objective-C - Is !! BOOL Beneficial

- (BOOL) hasId { 
    return !!hasId_; 
} 
- (void) setHasId:(BOOL) value { 
    hasId_ = !!value; 
} 

nunca he visto este patrón antes, y me pregunto si hay algún beneficio en su uso. ¿La doble negación hace algo útil?

+0

la única vez que he visto que era para una clase que no tenía una forma directa de enviar a bool, por lo que no podían hacer 'if (myInstance)', pero sobrecargó el operador '!' Único , entonces harían 'if (!! myInstance)'. Pero en tu caso, no tengo idea. – filipe

Respuesta

13

El operador booleano doble simplemente se asegura de que el valor devuelto es un 1 o un 0. Eso es todo:)

+5

... que impide el código como 'obj.hasId = 42; if (obj.hasId == YES) 'de fallar la condición. Técnicamente, 'SÍ' está (actualmente) mapeado a 1, por lo que los valores enteros son diferentes. Conceptualmente, sin embargo, tanto 42 como 'SÍ' representan un verdadero valor booleano. La doble negación colapsa esa asignación de 42 a una asignación 'SÍ'. –

+0

Gracias, supuse que probablemente era algo así. ¿Pero es útil hacerlo de esa manera/se evitan los posibles errores?Al igual que quizás esto evita un error inesperado al hacer una comparación en forma de 'if (obj.hasId == YES)'? Aunque no es una comparación en mal estilo de todos modos? Editar: no importa, Bavarious me ganó. – aroth

+0

Cierto, pero a veces es útil, para convertir a 1 o 0, como SQLite guarda campos booleanos solo en 1 o 0. –

3

! es un operador de negación lógica. Entonces, si setHasId: se pasó, por ejemplo, 0x2, la doble negación almacenaría 0x1.

1

Es equivalente a:

hasId_ = value ? 1 : 0; 

Es útil en algunos casos, ya que si lo hace:

BOOL x = y & MY_FLAG; 

Usted puede obtener 0 si MY_FLAG se establece, ya que el resultado se trunca a el tamaño de un BOOL (8 bits). Esto es inesperado. Por las mismas razones, la gente a veces prefiere que BOOL sea 0 o 1 (por lo que las operaciones de bit funcionan como se esperaba). Por lo general es innecesario.

En idiomas con un tipo incorporado bool como C (a partir de C99) y C++, la conversión de un número entero a bool hace esto automáticamente.

0

tiene más sentido en algunos otros casos, por ejemplo cuando usted está volviendo BOOL, pero no quieren poner en una declaración if.

- (BOOL)isMyVarSet 
{ 
    return !!myVar; 
} 

En este caso no puedo volver porque es myVar no es BOOL (este es un ejemplo muy artificial, no puedo sacar uno decente de mis proyectos).

0

que he usado antes, y yo creo:

if (!!myVar)

es equivalente a:

if (myVar != nil)

Básicamente, lo uso para verificar el valor de algo.

Debo admitir ... esta no es probablemente la mejor práctica o la forma más comprendida para lograr este objetivo.

+0

La diferencia es: (myVar! = Nil) es bastante obvio, mientras que (!! myVar) lo detiene en sus pistas, tiene que pensar mucho en lo que hace, y luego tiene que pensar aún más en averiguar si quien lo escribió realmente lo dijo. Lo mejor es expresar claramente lo que quieres decir. – gnasher729

+0

Totalmente de acuerdo! Mi respuesta es 3 años, y ABSOLUTAMENTE no escribiría !! var en ningún código nuevo hoy! – mbm29414