Я часто видел "assert" в iOS-коде, я google, и узнал, что он утверждает true или false.
Я хочу знать, будет ли это автоматически отключено в режиме выпуска?
Я часто видел "assert" в iOS-коде, я google, и узнал, что он утверждает true или false.
Я хочу знать, будет ли это автоматически отключено в режиме выпуска?
Используйте 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 методах.
Здесь я предоставлю мета-ответ:
Оба @CocoaFu и @dasblinkenlight являются правильными. NS_BLOCK_ASSERTIONS
отключается NSAssert()
, а NDEBUG
отключается assert()
. Вам нужны оба, если вы используете оба.
Обновление: Проверено, что это работает и в Xcode 8.
В Xcode 7 зайдите в настройки сборки проекта и найдите "Assert" в строке поиска. Это показывает раздел "Apple LLVM 7.0 - Предварительная обработка". Существует настройка под названием "Включить утверждения утверждений".
Я успешно включил/отключил NSAssert.
Как сказал Заф, -DNS_BLOCK_ASSERTIONS=1
установлен для выпуска. Однако, если вы хотите проверить это.
Сначала в документах обратите внимание, что NSAssert отключен макросом NS_BLOCK_ASSERTIONS
. Затем добавьте это в сборку и соблюдайте ее в порядке:
#ifdef NS_BLOCK_ASSERTIONS
#error Error - NS_BLOCK_ASSERTIONS is defined
#endif
Затем измените схему на выпуск (cmd-shift-<)
Затем обратите внимание, что сборка не выполняется. Поэтому NS_BLOCK_ASSERTIONS
определено значение NSAssert
отключено.
Атрибуты условно компилируются из вашего кода, когда NDEBUG
определен. Если вы определяете NDEBUG=1
в соответствующем разделе настроек сборки, вы дезактивируете утверждения в своем коде независимо от режима выпуска или отладки.
Теперь, начиная с Xcode 6, настройка ENABLE_NS_ASSERTIONS
, которая по умолчанию установлена на 1
для конфигураций Debug и 0
для Release.
Вы можете выбрать его для сборки Release в командной строке, передав аргумент ENABLE_NS_ASSERTIONS=1
, который я делаю для запуска модульных тестов, которые проверяют условия утверждения, но в противном случае следует запускать с флагом DEBUG
.
Вот что я делаю в верхней части моего 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
).