NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Le code ci-dessus produit une erreur:
Les valeurs de type «NSInteger» ne doivent pas être utilisées comme arguments de format; ajoutez plutôt une distribution explicite à 'long'
Le NSLog
message corrigé est en fait NSLog(@"%lg", (long) myInt);
. Pourquoi dois-je convertir la valeur entière de myInt
en long
si je veux que la valeur s'affiche?
objective-c
xcode
casting
nsinteger
Daniel Lee
la source
la source
NSLog(@"%ld", (long) myInt);
, lelong
casting est de faire correspondre lel
qualificatif de%ld
, mais tout cela est inutile carNSLog(@"%d", myInt);
c'est suffisant (étant donné que nous pouvons voir que cemyInt
n'est pas le caslong
. En bout de ligne, vous lancezmyInt
si vous utilisez un qualificatif long au format chaîne, mais pas besoin d'utiliser le qualificatif de format de chaîne longue ou delong
transtyper ici.NSInteger
n'est pas long), mais il semble que vous compiliez avec la cible OS X (oùNSInteger
estlong
).Réponses:
Vous obtenez cet avertissement si vous compilez sur OS X (64 bits), car sur cette plate-forme
NSInteger
est défini commelong
et est un entier 64 bits. Le%i
format, en revanche, est pourint
, qui est 32 bits. Ainsi, le format et le paramètre réel ne correspondent pas en taille.Puisqu'il
NSInteger
s'agit de 32 bits ou 64 bits, selon la plate-forme, le compilateur recommande d'ajouter un cast àlong
généralement.Mise à jour: Étant donné qu'iOS 7 prend désormais également en charge 64 bits, vous pouvez obtenir le même avertissement lors de la compilation pour iOS.
la source
NSLog(@"%ld", (long) myInt)
, cela fonctionne correctement sur 32 bits et 64 bits.long myInt = [myNumber longValue];
. Mais de nombreuses méthodes (Core) Foundation utilisent NS (U) Integer comme paramètre ou valeur de retour, de sorte que le problème général demeure. Il peut également être judicieux dans votre application d'utiliser NS (U) Integer pour obtenir une plus grande plage disponible sur les appareils 64 bits.Vous n'avez pas besoin de convertir quoi que ce soit si vos spécificateurs de format correspondent à vos types de données. Voir la réponse de Martin R pour plus de détails sur la façon dont
NSInteger
est définie en termes de types natifs.Donc, pour le code destiné à être construit pour les environnements 64 bits, vous pouvez écrire vos instructions de journal comme ceci:
tandis que pour les environnements 32 bits, vous pouvez écrire:
et tout fonctionnera sans moulages.
Une des raisons d'utiliser des casts de toute façon est que le bon code a tendance à être porté sur toutes les plates-formes, et si vous cast vos variables explicitement, il compilera proprement sur 32 et 64 bits:
Et notez que cela est vrai non seulement pour les instructions NSLog, qui ne sont que des aides au débogage après tout, mais aussi pour
[NSString stringWithFormat:]
les divers messages dérivés, qui sont des éléments légitimes du code de production.la source
Au lieu de passer un NSInteger à NSLog, passez simplement un NSNumber. Cela contournera tous les casts et choisira le bon spécificateur de format de chaîne.
Cela fonctionne également pour NSUIntegers sans avoir à vous en soucier. Voir la réponse à NSInteger et NSUInteger dans un environnement mixte 64 bits / 32 bits
la source
Il garde l'avertissement lors de l'utilisation
NSLog(@"%ld", (long)myInt);
, mais arrête l'avertissement après la déclaration de modificationlong myInt = 1804809223;
dans iOS 10.la source
OS X utilise plusieurs types de données (NSInteger, NSUInteger, CGFloat et CFIndex) pour fournir un moyen cohérent de représenter les valeurs dans les environnements 32 et 64 bits. Dans un environnement 32 bits, NSInteger et NSUInteger sont définis respectivement comme int et unsigned int. Dans les environnements 64 bits, NSInteger et NSUInteger sont définis respectivement comme long et unsigned long. Pour éviter d'avoir à utiliser différents spécificateurs de type printf en fonction de la plate-forme, vous pouvez utiliser les spécificateurs indiqués dans ce lien pour les environnements 32 bits et 64 bits.
la source