web-dev-qa-db-fra.com

NSInteger et NSUInteger dans un environnement mixte 64 bits / 32 bits

J'ai une bonne quantité de spécificateurs de format de chaîne dans les appels NSLog/NSAssert, etc. qui utilisent respectivement %d Et %u Avec les types NSInteger (= int on 32bit) et NSUInteger (= unsigned int on 32bit).

Lors de la conversion de l'application en 64 bits, cela donne des avertissements (bien sûr), car %ld %lu Est attendu pour ce qui est maintenant devenu un type long et unsigned long.

La simple conversion des spécificateurs de format introduira bien sûr les avertissements inversés dans la version 32 bits.
.

Mais je me demandais s'il y avait peut-être des spécificateurs de format spécifiquement pour les types NSInteger et NSUInteger qui fonctionneraient sur les deux architectures sans transtypage?

28
Pieter

Je pense que le moyen le plus sûr est de les placer dans des instances NSNumber.

NSLog(@"Number is %@", @(number)); // use the highest level of abstraction

Cette boxe n'a généralement pas à créer un nouvel objet grâce à pointeur tagué magie.

Si vous voulez vraiment ne pas utiliser NSNumber, vous pouvez convertir les types primitifs manuellement, comme d'autres l'ont suggéré:

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

Vous pouvez aussi utiliser %zd (NSInteger) et %tu (NSUInteger) lors de la connexion à la console.

NSInteger integer = 1;
NSLog(@"first number: %zd", integer);

NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);

Également disponible ici.

38
d0m1n1k

Non , (malheureusement) il n'y a pas de format printf qui correspond directement à NS(U)Integer. Donc, pour le code indépendant de l'architecture, vous devez tout convertir en variante "longue" (comme le suggère le Xcode "Fix-it"):

NSInteger i = ...;
NSLog(@"%ld", (long)i);

La seule alternative que je connaisse est de types de fondation lors de la compilation pour l'architecture arm64 et 32 ​​bits :

// In the precompiled header file:
#if __LP64__
#define NSI "ld"
#define NSU "lu"
#else
#define NSI "d"
#define NSU "u"
#endif

NSInteger i = ...;
NSLog(@"i=%"NSI, i);

en utilisant des macros de préprocesseur (mais même l'auteur de cette réponse appelle cela une "approche certes horrible").

4
Martin R