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 типа который бы работал на обеих архитектурах без приведения?

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

Единственная альтернатива, которую я знаю, - это использование типов 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);

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

Другие вопросы по тегам