147 votes

Pourquoi un NSInteger variable ont à typecasted de type long?

NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <==== 

Le ci-dessus obtient une erreur, comme indiqué par la flèche: les Valeurs de type "NSInteger" ne doit pas être utilisé comme format d'arguments: ajouter un cast explicite "long" à la place.

Le bon NSLog message est en fait NSLog(@"%lg", (long) myInt); Pourquoi dois-je convertir la valeur de l'entier de myInt à la longue, si je veux de la valeur à afficher?

194voto

Martin R Points 105727

Vous obtenez ce message d'avertissement si vous compilez sur OS X (64 bits), parce que sur cette plate-forme NSInteger est défini comme long et est un entier de 64 bits. L' %i format, d'autre part, est pour int, qui est de 32 bits. Si le format et le paramètre ne correspond pas à la taille.

Depuis NSInteger 32 bits ou 64 bits, selon la plate-forme, le compilateur recommande pour ajouter un cast long généralement.

Mise à jour: Depuis iOS 7 prend en charge 64-bit aujourd'hui, vous pouvez obtenir le message d'avertissement lors de la compilation pour iOS.

41voto

Monolo Points 11263

Vous n'avez pas à jeter pour rien si votre spécificateurs de format correspondent à vos types de données. Voir Martin R réponse pour lesquels les types natifs NSInteger est défini comme.

Donc, sur OS X 64 bits, vous pouvez écrire votre journal de ce type de déclarations:

NSLog(@"%ld",  myInt); 

alors que sur iOS, vous pouvez écrire:

NSLog(@"%d",  myInt); 

et ce sera sans moulages.

L'une des raisons d'utiliser des moulages de toute façon, au moins dans le non-code de l'INTERFACE utilisateur, c'est que le code de bonne tend à être porté sur les plates-formes, et si vous avez jeté votre explicitement les variables de compiler proprement sur les versions 32 et 64 bits:

NSLog(@"%ld",  (long)myInt);

Ce sera également aider votre iOS code dans une transition vers le 64 bits, faut-il jamais venu à iOS. Ou quand iOS et OS X sont fusionnés ensemble, en bas de la ligne.

Et de l'avis cela ne va pas juste pour NSLog déclarations, qui sont juste de débogage sida après tout, mais aussi pour [NSString stringWithFormat:] et les amis, qui sont légitimes des éléments de code de production.

22voto

orkoden Points 2262

Plutôt que de transmettre un NSInteger à NSLog, il suffit de passer un NSNumber. Cela permettra de se déplacer dans toutes les fontes et le choix de la chaîne de droite spécificateur de format.

NSNumber foo = @9000;
NSLog(@"foo: %@", foo);
NSInteger bar = 9001;
NSLog(@"bar: %@", @(bar));

Il travaille également pour NSUIntegers sans avoir à vous soucier de cela. Voir la réponse à la NSInteger et NSUInteger dans un mélange de 64 bits / 32 bits de l'environnement

1voto

CMash Points 148

Citant ilya n.'s réponse ici , car il semble être une bonne solution que j'ai utilisé moi-même:

I think the safest way is to box them into NSNumber instances.

NSLog(@"Number is %@", @(number)); // use the highest level of abstraction
This boxing doesn't usually have to create a new object thanks to tagged pointer magic.

If you really don't want to use NSNumber, you can cast primitive types manually, as others suggested:

NSLog(@"Number is %ld", (long)number); // works the same on 32-bit and 64-bit

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X