NSInteger myInt = 1804809223;
NSLog(@"%i", myInt); <====
Код выше выдает ошибку:
Значения типа NSInteger не должны использоваться в качестве аргументов формата; вместо этого добавьте явное приведение к 'long'
Исправленное NSLog
сообщение на самом деле NSLog(@"%lg", (long) myInt);
. Почему мне нужно преобразовать целочисленное значение myInt
в, long
если я хочу, чтобы это значение отображалось?
objective-c
xcode
casting
nsinteger
Дэниел Ли
источник
источник
NSLog(@"%ld", (long) myInt);
,long
приведение в соответствие сl
классификатором%ld
, но все это не нужно, так какNSLog(@"%d", myInt);
достаточно (учитывая, что мы видим, чтоmyInt
это не такlong
. Нижняя строка, вы приводите,myInt
если использовать длинный классификатор в формате строка, но не нужно использовать ни спецификатор формата длинной строки, ниlong
приведение здесьNSInteger
это не долго), но это звучит , как вы собираете с целью OS X (гдеNSInteger
естьlong
).Ответы:
Вы получаете это предупреждение, если вы компилируете в OS X (64-битной), потому что на этой платформе
NSInteger
определено какlong
и является 64-битным целым числом.%i
Формат, с другой стороны, дляint
, который является 32-битным. Таким образом, формат и фактический параметр не совпадают по размеру.Так
NSInteger
как 32-битный или 64-битный, в зависимости от платформы, компилятор рекомендует добавлять приведение кlong
вообще.Обновление: поскольку iOS 7 теперь также поддерживает 64-битную версию, вы можете получить то же предупреждение при компиляции для iOS.
источник
NSLog(@"%ld", (long) myInt)
, он работает на 32-битной и 64-битной корректно.long myInt = [myNumber longValue];
. Но многие (базовые) методы Foundation используют NS (U) Integer в качестве параметра или возвращаемого значения, поэтому общая проблема остается. Также в вашем приложении может иметь смысл использовать NS (U) Integer, чтобы получить больший доступный диапазон на 64-битных устройствах.Вам не нужно приводить что-либо, если ваши спецификаторы формата соответствуют вашим типам данных. См. Ответ Мартина Р. для получения подробной информации о том, как
NSInteger
определяется в терминах нативных типов.Таким образом, для кода, предназначенного для построения для 64-битных сред, вы можете написать свои операторы журнала следующим образом:
в то время как для 32-битных сред вы можете написать:
и все это будет работать без приведения.
В любом случае, одна из причин использования приведений заключается в том, что хороший код имеет тенденцию переноситься на разные платформы, и если вы явно приведете свои переменные, он будет скомпилирован чисто как в 32-, так и в 64-разрядных системах:
И обратите внимание, что это верно не только для операторов NSLog, которые, в конце концов, просто являются средствами отладки, но также для
[NSString stringWithFormat:]
различных производных сообщений, которые являются законными элементами производственного кода.источник
Вместо передачи NSInteger в NSLog, просто передайте NSNumber. Это обойдет все приведения и выберет правильный спецификатор формата строки.
Это также работает для NSUIntegers, не беспокоясь об этом. Смотрите ответ NSInteger и NSUInteger в смешанной 64-битной / 32-битной среде
источник
Он сохраняет предупреждение при использовании
NSLog(@"%ld", (long)myInt);
, но останавливает предупреждение после объявления измененияlong myInt = 1804809223;
в iOS 10.источник
OS X использует несколько типов данных - NSInteger, NSUInteger, CGFloat и CFIndex - для обеспечения согласованных средств представления значений в 32- и 64-разрядных средах. В 32-разрядной среде NSInteger и NSUInteger определяются как int и unsigned int соответственно. В 64-разрядных средах NSInteger и NSUInteger определяются как long и unsigned long соответственно. Чтобы избежать необходимости использовать разные спецификаторы типа printf-стиля в зависимости от платформы, вы можете использовать спецификаторы, показанные в этой ссылке, как для 32-битной, так и для 64-битной среды.
источник