NSInteger и NSUInteger в смешанной 64-битной / 32-битной среде

у меня есть достаточное количество спецификаторов строкового формата в NSLog/NSAssert и т. д. вызовы, которые используют %d и %u С NSInteger (= int on 32bit) и NSUInteger (= unsigned int on 32bit) типы соответственно.

при преобразовании приложения в 64bit это дает предупреждения (конечно), как %ld %lu ожидается то, что теперь стало long и unsigned long тип.

простое преобразование спецификаторов формата, конечно, введет обратные предупреждения в 32-битной сборке.
Так что единственное решение, которое я вижу become warning free использует 64-битные спецификаторы, и приведение к 64-битным типам значений везде, где предупреждение дается в 32-битной сборке.

но мне было интересно, возможно, есть спецификаторы формата специально для NSInteger и NSUInteger тип, который будет работать на обеих архитектурах без литья?

3 ответов


Я думаю, что самый безопасный способ-упаковать их в NSNumber экземпляров.

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

этот бокс обычно не нужно создавать новый объект благодаря тегированный указатель магия.

если вы действительно не хочу использовать NSNumber, вы можете использовать примитивные типы вручную, как предлагали другие:

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

вы также можете использовать %zd (NSInteger) и %tu (NSUInteger) при входе в консоль.

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

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

также можно найти здесь.


нет, (к сожалению) нет формата printf, который напрямую соответствует NS(U)Integer. Поэтому для независимого от архитектуры кода Вы должны преобразовать все в " длинный" вариант (как предлагает Xcode "Fix-it"):

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

единственная альтернатива, которую я знаю, это от типы фундаментов при компиляции для arm64 и 32-разрядной архитектуры:

// 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);

использование макросов препроцессора (но даже автор этого ответа называет его ля "по общему признанию, ужасный подход").