NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Le code ci-dessus génère une erreur:
Values of type "NSInteger" should not be used as format arguments: add an explicit cast to 'long' instead.
Le bon message NSLog
est en fait NSLog(@"%lg", (long) myInt);
Pourquoi dois-je convertir la valeur entière de myInt en long si je souhaite que la valeur soit affichée?
Vous obtenez cet avertissement si vous compilez sous OS X (64 bits), car sur cette plate-forme, NSInteger
est défini en tant que long
et correspond à un entier 64 bits. Le format %i
, En revanche, est destiné à int
, qui est 32 bits. Donc, le format et le paramètre réel ne correspondent pas en taille.
Puisque NSInteger
est 32 bits ou 64 bits, selon la plate-forme, le compilateur recommande d'ajouter un transtypage à long
en général.
Mise à jour: Étant donné qu'iOS 7 prend également en charge la version 64 bits, vous pouvez obtenir le même avertissement lors de la compilation pour iOS.
Vous n'avez rien à rediffuser si vos spécificateurs de format correspondent à vos types de données. Voir la réponse de Martin R pour quels types natifs NSInteger
est défini par.
Ainsi, sur OS X 64 bits, vous pouvez écrire vos instructions de journal de la manière suivante:
NSLog(@"%ld", myInt);
sur iOS, vous pouvez écrire:
NSLog(@"%d", myInt);
et tout fonctionnera sans plâtre.
De toute façon, une des raisons d'utiliser des transtypes, du moins dans le code sans interface utilisateur, est qu'un bon code a tendance à être porté sur toutes les plates-formes, et si vous transformez explicitement vos variables, il compilera proprement à la fois en 32 et 64 bits:
NSLog(@"%ld", (long)myInt);
Cela aidera également votre code iOS lors du passage à la version 64 bits, si jamais il venait à iOS. Ou lorsque iOS et OS X sont fusionnés sur toute la ligne.
Et notez que cela ne vaut pas seulement pour les instructions NSLog, qui ne sont finalement que des aides au débogage, mais également pour [NSString stringWithFormat:]
et amis, qui sont des éléments légitimes du code de production.
Au lieu de transmettre un NSInteger à NSLog, transmettez simplement un NSNumber. Cela permettra de contourner tous les moulages et de choisir le bon spécificateur de format de chaîne.
NSNumber foo = @9000;
NSLog(@"foo: %@", foo);
NSInteger bar = 9001;
NSLog(@"bar: %@", @(bar));
Cela fonctionne également pour NSUIntegers sans avoir à vous soucier de cela. Voir la réponse à NSInteger et NSUInteger dans un environnement mixte 64 bits/32 bits
Il garde l'avertissement lorsque vous utilisez NSLog(@"%ld", (long)myInt);
, mais arrête l'avertissement après la déclaration de modification en long myInt = 1804809223;
dans iOS 10.