Как узнать, отключен ли NSAssert в сборках релизов?

Я часто видел "assert" в iOS-коде, я google, и узнал, что он утверждает true или false.

Я хочу знать, будет ли это автоматически отключено в режиме выпуска?

Ответ 1

Используйте NSAssert() и его спутников.

в проекте определите NS_BLOCK_ASSERTIONS для вашей конфигурации выпуска.

Xcode 4 tremplates отключает NSAsserts в конфигурации релиза. Он добавляет

-DNS_BLOCK_ASSERTIONS=1

в "Другие флаги C" для "Release".

Из документации:

Утверждения отключены, если задан макрос препроцессора NS_BLOCK_ASSERTIONS.

Макрос NSAssert оценивает условие и служит в качестве переднего конца обработчика утверждения.

Каждый поток имеет свой собственный обработчик утверждения, который является объектом класса NSAssertionHandler. При вызове обработчик assert выводит сообщение об ошибке, включающее имена методов и классов (или имя функции). Затем он вызывает исключение NSInternalInconsistencyException. Если условие равно NO, макрос вызывает handleFailureInMethod:object:file:lineNumber:description: в обработчике утверждения для текущего потока, передавая desc в качестве строки описания.

Этот макрос должен использоваться только в Objective-C методах.

Ответ 2

Здесь я предоставлю мета-ответ:

Оба @CocoaFu и @dasblinkenlight являются правильными. NS_BLOCK_ASSERTIONS отключается NSAssert(), а NDEBUG отключается assert(). Вам нужны оба, если вы используете оба.

Ответ 3

Обновление: Проверено, что это работает и в Xcode 8.

В Xcode 7 зайдите в настройки сборки проекта и найдите "Assert" в строке поиска. Это показывает раздел "Apple LLVM 7.0 - Предварительная обработка". Существует настройка под названием "Включить утверждения утверждений".

Я успешно включил/отключил NSAssert.

введите описание изображения здесь

Ответ 4

Как сказал Заф, -DNS_BLOCK_ASSERTIONS=1 установлен для выпуска. Однако, если вы хотите проверить это.

Сначала в документах обратите внимание, что NSAssert отключен макросом NS_BLOCK_ASSERTIONS. Затем добавьте это в сборку и соблюдайте ее в порядке:

#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif

Затем измените схему на выпуск (cmd-shift-<)

enter image description here

Затем обратите внимание, что сборка не выполняется. Поэтому NS_BLOCK_ASSERTIONS определено значение NSAssert отключено.

Ответ 5

Атрибуты условно компилируются из вашего кода, когда NDEBUG определен. Если вы определяете NDEBUG=1 в соответствующем разделе настроек сборки, вы дезактивируете утверждения в своем коде независимо от режима выпуска или отладки.

Ответ 6

Теперь, начиная с Xcode 6, настройка ENABLE_NS_ASSERTIONS, которая по умолчанию установлена ​​на 1 для конфигураций Debug и 0 для Release.

Вы можете выбрать его для сборки Release в командной строке, передав аргумент ENABLE_NS_ASSERTIONS=1, который я делаю для запуска модульных тестов, которые проверяют условия утверждения, но в противном случае следует запускать с флагом DEBUG.

Ответ 7

Вот что я делаю в верхней части моего main():

#if defined(NDEBUG)
{
  // The assertion code below should be compiled out of existence in a release
  // build.  Log an error and abort the program if it is not.
  bool ok = true;
  NSCAssert(ok = false, @"NS assertions should be disabled but are not");
  if (!ok)
  {
    NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined");
    return -1;
  }
}
#endif

Обратите внимание, что поскольку main() является функцией C, а не функцией Objective-C, используется NSCAssert, а не NSAssert. (NSAssert ожидает self).