objective-c specifiers Почему только NSLog предупреждает меня об использовании спецификатора формата строки% lu для NSUInteger?



swift string format specifiers (3)

Все устройства, на которых работает iOS, являются 32-битными. Если вы хотите заставить замолчать предупреждение:

NSLog(@"row: %lu", (unsigned long)indexPath.row);

[Редактировать: Что касается iPhone 5s, больше не правда, что iOS всегда 32-битная.]

По какой-то причине я получаю ошибку компиляции при попытке сделать следующее:

NSLog(@"row: %lu", indexPath.row);

где row имеет тип NSUInteger . Я получаю ошибку

Преобразование указывает тип «unsigned long», но аргумент имеет тип «NSUInteger» (он же «unsigned int»)

Я могу сделать следующее без ошибок компиляции:

NSString * string = [NSString stringWithFormat:@"row: %lu", indexPath.row];

Я использую одну и ту же строку формата и аргумент замещения в обоих случаях, но почему NSLog -stringWithFormat: , пока -stringWithFormat: кажется, совершенно доволен? Мой компилятор LLVM 1.6.


Я столкнулся с этой же проблемой, и хотя @Wevah правильный и его ответ работает отлично, есть еще один вариант, который не требует никаких изменений кода. Подробности смотрите в следующей документации Apple:

Руководство по строковому программированию | Зависимости платформы

64-битное руководство по переходу для какао | Сборка 32-битных, как 64-битных

NS_BUILD_32_LIKE_64 препроцессора NS_BUILD_32_LIKE_64 весьма полезен. Вы можете установить его в настройках проекта GCC_PREPROCESSOR_DEFINITIONS (в разделе GCC_PREPROCESSOR_DEFINITIONS ) или просто поместить #define NS_BUILD_32_LIKE_64 1 в файл предварительно скомпилированного заголовка (.pch). В моем приложении это исключило 11 предупреждений без каких-либо изменений кода.

Это работает, потому что unsigned int и unsigned long имеют одинаковый размер (4 байта) на iOS, поэтому изменение typedef NSUInteger делает компилятор (и разработчика) счастливым, но аппаратному обеспечению все равно, поскольку он просто выполняет целочисленную математику в оба случая. :-)


В документации Apple рекомендуется преобразовывать 64-битное значение в 32-битное с использованием% lu и% ld. Это создает проблему, если вы действительно используете дополнительные 32 бита. Строки формата% qu и% qd задают 64-битное значение (без знака и со знаком соответственно). Если вам нужен код, который будет компилироваться в любом режиме, то значения, объявленные как NSUInteger или NSInteger, должны быть преобразованы в UInt64 или SInt64 в списке параметров, чтобы избежать предупреждения.