objective c - Compara un NSNumber con un int
objective-c compare (5)
Tengo una pregunta simple (creo): estoy tratando de comparar un NSNumber con un int, para ver si es 0 o 1. Aquí está el código:
id i = [dictionary objectForKey:@"error"]; //class = NSCFNumber
NSLog(@"%@ == 0 -> %@", i, i == 0);
NSLog(@"%@ == 0 -> %@", i, [i compare:[NSNumber numberWithBool:NO]]);
Intenté esto a métodos pero obtengo nulo como resultado:
2010-10-17 21:57:49.065 Api[15152:a0f] 0 == 0 -> (null)
2010-10-17 21:57:49.065 Api[15152:a0f] 0 == 0 -> (null)
¿Me puedes ayudar?
El resultado de la comparación es un BOOL que no es un objeto Objective-C. Por lo tanto, no debe imprimirlo utilizando
%@
. Intente%d
lugar (muestra 0 o 1).[a compare:b]
devuelve -1 sia < b
, 0 sia == b
y 1 sia > b
. Así que se espera su segundo resultado.No puede comparar un NSNumber directamente con un entero. Que
i == 0
es en realidad una comparación de punteros que verifica sii
es NULL (0), que por supuesto es FALSO si ese número existe. Así que también se espera el 1er resultado.Si desea verificar la igualdad, use
[a isEqualToNumber:b]
. Alternativamente, puede extraer el entero con[a intValue]
y comparar con otro entero directamente.
Así que lo siguiente debería funcionar:
NSLog(@"%@ == 0 -> %d", i, [i isEqualToNumber:[NSNumber numberWithInt:0]]);
NSLog(@"%@ == 0 -> %d", i, [i intValue] == 0);
Si el "número" es de hecho un valor booleano, es mejor tomar el valor -boolValue
.
NSLog(@"%@ == 0 -> %d", i, ! [i boolValue]);
Aquí está comparando el puntero del objeto i con 0, lo que me temo que no es lo que quiere.
Lo más probable es que quieras comparar el valor de i:
if ([i intValue]==0) {
...
}
Esto funciono
if (thevariable.intValue==0) {
...
}
Puedes escribir fácilmente:
NSNumber *number = [NSNumber numberWithInt:123];
int integer = 1234;
NSLog(@"%@ == %i : %i", number, integer, [number intValue] == integer);
La salida debe ser
123 == 1234 : 0
¡Espero que yo puedo ayudarle!
Tienes dos problemas:
- Confunde el objeto NSNumber con el valor que representa.
-
NSLog
cadena de formatoNSLog
no coincide con los tipos de argumentos que proporciona.
Respecto al primer problema: i
es una dirección, tal vez algo como 0x1f84b
. Cuando prueba si i == 0
, está probando si i == NULL
. En este caso, eso significa que está comprobando si la clave "error" estaba presente en el diccionario o no, ya que al buscar una clave inexistente se obtiene un valor NULL
.
[i intValue]
, por otro lado, es un entero. Si el NSNumber
contiene un valor representable como un entero, este será el valor del NSNumber
. Eso es lo que ve cuando imprime la NSNumber
del NSNumber
utilizando el especificador de formato %@
.
Respecto al segundo problema: las comparaciones en C y Objective-C devuelven un entero, ya sea 0 (que significa falso) o 1 (que significa verdadero). Para imprimir directamente el resultado de una comparación, debe utilizar el especificador de formato de enteros. En realidad, hay dos especificadores de este tipo, %i
y %d
. Podría ajustar el resultado de la comparación en un NSNumber y usar %@
para imprimir eso, pero eso es más trabajo de lo que vale.
Entonces, esto es lo que deberías estar haciendo:
NSNumber *i = [dictionary objectForKey:@"error"];
BOOL haveValue = (i != NULL);
if (haveValue) {
int iValue = [i intValue];
NSLog(@"%d == 0 -> %d", iValue, iValue == 0);
NSLog(@"%@ compared to 0 -> %d", i, [i compare:[NSNumber numberWithInt:0]]);
} else {
NSLog(@"*** Dictionary has no value for key /"error/"!");
}