Почему NSAssert1 и т. Д. Вместо NSAssert? - PullRequest
7 голосов
/ 03 июня 2011

Я думал, NSAssert не может использовать printf спецификаторы, но это:

NSAssert(0, @"%@%@", @"foo", @"bar");

работает так, как вы ожидаете:

*** Assertion failure in -[MyClass myMethod], <Path>/MyClass.m:84
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
    reason: 'foobar'

Так какой смыслиспользования NSAssert1, NSAssert2 и т. д., когда NSAssert работает?

Это с Xcode 4.0 и iOS 4.3 SDK, если это имеет значение.(Если этого не произойдет, я обновлю теги.)

Ответы [ 2 ]

18 голосов
/ 03 июня 2011

В текущих версиях NSAssert() используются переменные макросы препроцессора, т. Е. __VA_ARGS__.Поскольку макросы с переменным числом аргументов являются функцией C99, я предполагаю, что более старые версии SDK не допускали переменных аргументов в NSAssert(), следовательно, необходимы NSAssert1(), NSAssert2() и т. Д.

Если выпопробуйте скомпилировать

NSAssert(0, @"%@%@", @"foo", @"bar");

, используя -std=c89 или -ansi (ISO C90, более старая версия C, которая не поддерживает переменные макросы), вы получите ошибку компилятора:

error: too many arguments provided to function-like macro invocation
    NSAssert(0, @"%@%@", @"foo", @"bar");

Чтобы этот код компилировался с -std=c89 или -ansi, вам нужно использовать NSAssert2():

NSAssert2(0, @"%@%@", @"foo", @"bar");
0 голосов
/ 10 августа 2015

Отличный ответ от Бавария.

Просто добавляю к этому свой бит. Для людей, которые сталкиваются с проблемой Too many arguments provided to function-like macro invocation. Обратите внимание на часть, упомянутую @ Bavarious как -std=c89.

Вот как я избавился от этой проблемы.

  1. Зайдите в настройки сборки -> Apple LLVM 6.1
  2. Найти диалект языка C
  3. Изменить на -std=c99
...