Pourquoi un NSInteger variable doivent être moulés à long lorsqu'il est utilisé comme un argument de format?
NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Le code ci-dessus produit une erreur:
Values of type "NSInteger" should not be used as format arguments: add an explicit cast to 'long' instead.
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?
- si vous utilisez
NSLog(@"%ld", (long) myInt);
, lelong
casting est pour le faire correspondre avec lel
qualificatif de%ld
, mais tout cela est inutile, carNSLog(@"%d", myInt);
est suffisante (étant donné que nous pouvons voir quemyInt
n'est paslong
. Ligne de fond, vous lancezmyInt
si vous utilisez long de qualification de la chaîne de format, mais pas besoin d'utiliser soit en long format de la chaîne de qualifier oulong
exprimés ici. - Apparemment, il n'est pas vrai que NSLog(@"%i", myInt); est suffisant parce que vous obtiendrez le message d'erreur que j'ai indiqué ci-dessus.
- Voir Martin R du commentaire. Vous avez posté votre question avec iOS balise (où
NSInteger
n'est pas long) , mais il semble que vous êtes de la compilation avec OS X cible (oùNSInteger
estlong
). - Ahh, je vois. Je ne savais pas iOS et OSX rendrait le NSInteger différents dans le bit et le type.
Vous devez vous connecter pour publier un commentaire.
Vous obtenez ce message d'avertissement si vous compilez sur OS X (64 bits), parce que sur cette plate-forme
NSInteger
est défini commelong
et est un entier de 64 bits. Le%i
format, d'autre part, est pourint
, qui est de 32 bits. Si le format et le paramètre ne correspond pas à la taille.Depuis
NSInteger
est 32 bits ou 64 bits, selon la plate-forme, le compilateur recommandepour ajouter une troupe de
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.
NSLog(@"%ld", (long) myInt)
, il fonctionne sur 32-bits et 64-bits.long myInt = [myNumber longValue];
. Mais beaucoup (de Base)de la Fondation utilisation de méthodes NS(U)Entier comme paramètre ou la valeur de retour, de sorte que le problème général reste. Il peut aussi donner un sens à votre application pour utiliser NS(U)Entier à obtenir une plus grande gamme disponible sur 64 bits appareils.Vous n'avez pas à jeter pour rien si votre spécificateurs de format correspondent à vos types de données. Voir Martin R de réponse pour les natifs qui types
NSInteger
est défini comme.Donc sur OS X 64 bits, vous pouvez écrire votre journal de ce type de déclarations:
alors que sur iOS, vous pouvez écrire:
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:
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 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.Au lieu de passer 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.
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
Il garde avertissement lors de l'utilisation
NSLog(@"%ld", (long)myInt);
, mais s'arrête avertissement après la déclaration de changement àlong myInt = 1804809223;
dans iOS 10.OS X utilise plusieurs types de données—NSInteger, NSUInteger,CGFloat, et CFIndex—de fournir un moyen de représenter les valeurs en 32 et 64 bits environnements. Dans un environnement 32 bits, NSInteger et NSUInteger sont définis comme des int et unsigned int, respectivement. Dans les environnements 64 bits, NSInteger et NSUInteger sont définis comme long et unsigned long, respectivement. Pour éviter la nécessité d'utiliser différents printf style spécificateurs de type selon la plate-forme, vous pouvez utiliser les prescripteurs montré dans ce lien pour à la fois 32 bits et 64 bits de l'environnement.