NSInteger и NSUInteger в смешанной среде с 64 бит /32 бит
У меня есть множество спецификаторов формата строки в вызовах NSLog/NSAssert и т.д., которые используют %d
и %u
с типами NSInteger (= int on 32bit)
и NSUInteger (= unsigned int on 32bit)
соответственно.
При преобразовании приложения в 64 бит это дает предупреждения (конечно), поскольку ожидается %ld %lu
для того, что теперь стало типом long
и unsigned long
.
Простое преобразование спецификаторов формата, конечно, представит обратные предупреждения в 32-битной сборке.
Таким образом, единственное решение, которое я вижу, чтобы стать предупреждающим, - это использование 64-битных спецификаторов и приведение к 64-битным значениям везде, где в 32-битной сборке содержится предупреждение.
Но мне было интересно, могут ли быть спецификаторы формата специально для типов NSInteger
и NSUInteger
, которые будут работать на обеих архитектурах без кастования?
Ответы
Ответ 1
Я думаю, что самый безопасный способ - поместить их в экземпляры 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
Ответ 2
Вы также можете использовать %zd
(NSInteger
) и %tu
(NSUInteger
) при входе в консоль.
NSInteger integer = 1;
NSLog(@"first number: %zd", integer);
NSUInteger uinteger = 1;
NSLog(@"second number: %tu", uinteger);
Также можно найти здесь.
Ответ 3
Нет (к сожалению) нет формата printf, который непосредственно соответствует NS(U)Integer
.
Итак, для независимого от архитектуры кода вам нужно преобразовать все в "длинный"
вариант (как предполагает Xcode "Fix-it" ):
NSInteger i = ...;
NSLog(@"%ld", (long)i);
Единственная альтернатива, которую я знаю, это Типы Foundation при компиляции для 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);
с использованием макросов препроцессора (но даже автор этого ответа называет это
"по общему признанию, ужасный подход" ).