Для чего утверждения или NSAssert хороши на практике?

Введите следующее в терминале:

nohup gtk-window-decorator --replace &

Хотелось бы надеяться, вышеупомянутая команда должна решить Вашу проблему.

16
задан e.James 31 March 2011 в 13:57
поделиться

2 ответа

Широкое использование NSAssert () не превратит ObjC в Eiffel, но это по-прежнему неплохая практика, если вы помните, как он на самом деле реализован и что делает. Что следует помнить о NSAssert () :

Xcode не отключает NSAssert () в режиме выпуска по умолчанию. Вы должны не забыть добавить NS_BLOCK_ASSERTIONS в GCC_PREPROCESSOR_DEFINITIONS в вашем xcconfig. (Вы используете xcconfigs , верно?) Распространенная проблема заключается в утверждении ненулевого значения в тех случаях, когда nil будет работать спокойно; это может означать сбои в работе объектов, которые можно было бы корректно восстановить. Это не связано с макросом NDEBUG , используемым assert () , и вы должны не забыть определить оба типа, если ваш код включает оба типа утверждений.

Если вы скомпилируете NSAssert () в режиме Release, то вы не получите указания, где возникла проблема, когда клиенты отправят вам их журналы. Я лично оборачиваю NSAssert () в свои собственные макросы, которые всегда регистрируются, даже в режиме Release.

NSAssert () часто заставляет дублировать логику. Рассмотрим случай проверки указателя C ++ на NULL. Вы используете NSAssert () , но вы по-прежнему должны использовать простой тест if () , чтобы избежать сбоев в поле. Подобный дублированный код может стать источником ошибок, и я видел код, который дает сбой из-за недействительных утверждений. (К счастью, это обычно в режиме отладки! ) Я много спорил о том, как создать макрос, который бы сочетал бы утверждение и if () , но это сложно сделать, не будучи хрупким и не усложняя код для понимания.

Из-за последнего проблема, я обычно помещаю « NSAssert (NO, ...) » в предложение else {} , а не выполняю утверждение в начале метода. Это не идеально, потому что он отодвигает контракт от сигнатуры метода (тем самым уменьшая его документальное преимущество), но это наиболее эффективный подход, который я нашел на практике.

в предложении else {} вместо выполнения утверждения в начале метода. Это не идеально, потому что он отодвигает контракт от сигнатуры метода (тем самым уменьшая его документальное преимущество), но это наиболее эффективный подход, который я нашел на практике.

в предложении else {} вместо выполнения утверждения в начале метода. Это не идеально, потому что он отодвигает контракт от сигнатуры метода (тем самым уменьшая его документальное преимущество), но это наиболее эффективный подход, который я нашел на практике.

27
ответ дан 30 November 2019 в 15:44
поделиться

Отладка. Когда вы пишете код, вы почти всегда делаете предположения. Предположения о состоянии среды, значениях ваших параметров, ваших локальных переменных и полей и т. Д. Часто эти предположения просто ошибочны (старый коллега дал мне хорошую максиму, что "Предположение - мать всех fsckups") .

Утверждения существуют для подтверждения ваших предположений в тот момент, когда вы их делаете. У вас есть метод

void foo(int x)
{
   …
}

, который вы знаете и документировали, работает только для x> 5? Утверждайте!

Утверждения существуют наряду с модульным тестированием и формальными методами как часть хорошей практики кодирования. Хотя некоторые могут подумать, что комплексные модульные тесты гарантируют избыточность утверждений, это не так. Например, у вас может быть предположение о методе, которое, скажем, сотрудникам всегда больше 16 и меньше 100 лет, но кодекс этого не требует. Модульные тесты, которые передают эти параметры, пройдут успешно, но позже, когда вам понадобится использовать ваше предположение, у вас будет везде код, который прошел тесты, но ошибочен.

7
ответ дан 30 November 2019 в 15:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: