Подтвердить что ты не робот

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

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

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

где row имеет тип NSUInteger. Ошибка, которую я получаю, это

Conversion указывает тип "unsigned long", но аргумент имеет тип "NSUInteger" (aka "unsigned int" )

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

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

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

4b9b3361

Ответ 1

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

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

[Edit: Начиная с iPhone 5s, уже не так, что iOS всегда 32-разрядная.]

Ответ 2

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

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

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

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

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

Ответ 3

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