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);
использование макросов препроцессора (но даже автор этого ответа называет его ля "по общему признанию, ужасный подход").