web-dev-qa-db-fra.com

Comparer un NSNumber à un int

J'ai une simple question (je pense): J'essaie de comparer un NSNumber avec un int, pour voir s'il est 0 ou 1. Voici le code:

id i = [dictionary objectForKey:@"error"]; //class = NSCFNumber

NSLog(@"%@ == 0 -> %@", i, i == 0);
NSLog(@"%@ == 0 -> %@", i, [i compare:[NSNumber numberWithBool:NO]]);

J'ai essayé ceci aux méthodes mais j'obtiens null comme résultat:

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)

Pouvez-vous m'aider?

17
patrick
  1. Le résultat de la comparaison est un BOOL qui n'est pas un objet Objective-C. Par conséquent, vous devriez not l’imprimer en utilisant %@. Essayez %d à la place (affiche 0 ou 1).

  2. [a compare:b] renvoie -1 si a < b, 0 si a == b et 1 si a > b. Donc, votre 2ème résultat est attendu.

  3. Vous ne pouvez pas comparer directement un NSNumber avec un entier. Ce i == 0 est en fait une comparaison pointeur qui vérifie si i est NULL (0), ce qui est bien sûr FALSE si ce nombre existe. Donc, le premier résultat est également attendu.

  4. Si vous voulez vérifier l’égalité, utilisez [a isEqualToNumber:b] . Vous pouvez également extraire le nombre entier avec [a intValue] et le comparer directement avec un autre nombre entier.

Donc, ce qui suit devrait fonctionner:

NSLog(@"%@ == 0 -> %d", i, [i isEqualToNumber:[NSNumber numberWithInt:0]]);
NSLog(@"%@ == 0 -> %d", i, [i intValue] == 0);

Si le "nombre" est en fait un booléen, il vaut mieux prendre le -boolValue à la place.

NSLog(@"%@ == 0 -> %d", i, ! [i boolValue]);
45
kennytm

Ici, vous comparez le pointeur de l'objet i avec 0, ce qui, je le crains, n'est pas ce que vous voulez.

Vous voulez probablement comparer la valeur de i:

if ([i intValue]==0) {
  ...
}
9
Victor Jalencas

Vous pouvez facilement écrire:

NSNumber *number = [NSNumber numberWithInt:123];
int integer = 1234;

NSLog(@"%@ == %i : %i", number, integer, [number intValue] == integer);

La sortie devrait être

123 == 1234 : 0


J'espère pouvoir vous aider!

3
Paul Warkentin

Vous avez deux problèmes:

  • Vous confondez l'objet NSNumber avec la valeur qu'il représente.
  • Votre chaîne de formatage NSLogne correspond pas aux types des arguments que vous fournissez.

En ce qui concerne le premier problème: iest une adresse, peut-être quelque chose comme 0x1f84b. Lorsque vous testez si i == 0, vous testez si i == NULL. Dans ce cas, cela signifie que vous testez si la clé "erreur" était présente dans le dictionnaire ou non, car la recherche d'une clé inexistante génère un NULLname__.

[i intValue], en revanche, est un entier. Si NSNumbercontient une valeur représentable sous la forme d'un entier, il s'agira de la valeur de NSNumbername__. C'est ce que vous voyez lorsque vous imprimez la description de NSNumbername __ à l'aide du spécificateur de format %@.

Concernant le deuxième problème: les comparaisons en C et en Objective-C renvoient un entier, soit 0 (signifiant faux) ou 1 (signifiant vrai). Pour imprimer directement le résultat d'une comparaison, vous devez donc utiliser le spécificateur de format entier. Il existe en fait deux spécificateurs de ce type, %i et %d. Vous pouvez envelopper le résultat de la comparaison dans un NSNumber et utiliser %@ pour l’imprimer, mais c’est beaucoup plus de travail que ça en vaut la peine.

Alors, voici ce que vous devriez faire:

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\"!");
}
3
Jeremy W. Sherman

Cela a fonctionné

if (thevariable.intValue==0) {
  ...
}
0
Naishta