Нужно ли оставлять утверждения в производственных приложениях iOS? - PullRequest
9 голосов
/ 13 декабря 2011

Обычной практикой может быть помещение утверждений в код для проверки входных параметров, целостности данных и т. Д. Во время разработки приложения.

Я тестирую свои приложения, НО, учитывая, что я не Кнут (и он пишет чеки на 1 доллар), и я не могу позволить себе нанять большую команду полностью занятых специалистов по обеспечению качества, как это делают Я полагаю, что в некоторых компаниях, занимающихся разработкой программного обеспечения для медицинских и космических систем, во всех приложениях всегда будет много ошибок, которые еще никогда не были замечены во время тестирования или тестирования. Предположим, что в противном случае кажется интеллектуально нечестным. Итак, после тестирования приложения (и, очевидно, устранения всех ошибок, вызвавших любые ранее обнаруженные сбои ASSERT) и подготовки приложения к отправке в Apple, что следует делать со всеми проверками ASSERT в сборке выпуска / распространения? Оставить или нет?

Вот одна из причин, по которой следует оставить их: если приложение работает неправильно для некоторых пользователей, оно может быть оценено этими пользователями как 1-звездочное, и никто не скажет разработчику, почему достаточно подробно. Но если приложение аварийно завершает работу из-за сбоя ASSERT, оно все равно может получить оценку 1 звезда, но разработчик потенциально может получить некоторые аварийные дампы, косвенно через iTunes и iTunes Connect, если подключится достаточное количество пользователей, чтобы выяснить, что происходит не так. И если Apple отклонит приложение из-за новой аварии ASSERT, это предотвратит попадание плохой версии приложения на устройства клиента.

Ответы [ 4 ]

11 голосов
/ 13 декабря 2011

Оставьте их в точности по указанным вами причинам, а также потому, что в некоторых случаях они выступают в качестве комментариев (особенно когда речь идет о типах в Objective-C).И не беспокойтесь о падении производительности, если только это не станет проблемой, или вы не знаете, что находитесь в критической ситуации с производительностью, и конкретное утверждение будет выполняться сотни или тысячи раз в главном цикле выполнения.

Не могу не упомянуть эту статью о утверждениях против NSAssert.

Лично я начинаю удалять те, которые я вставил для целей отладки, но если вы используете утверждения дляпроверить целостность данных, параметры, зависимости от ресурсов и другие связанные вещи - возможно, вы могли бы вместо этого сами генерировать исключения, что может быть мудрее - тогда я бы оставил их в.

Примечание: Еще один момент заключается в том, что простое удаление подтверждений является совершенно глупым, поскольку ваше приложение будет либо аварийно завершать работу, либо находиться в несовместимом состоянии, оба из которых хуже, чем аварийные сбои, что вы можете распознать из журналов сбоев (так что оставляйте подтверждения в),Заменить утверждения на операторы if, с другой стороны, это может быть хорошо.

5 голосов
/ 08 января 2012

Моя рекомендация: по умолчанию вы должны оставить их ON . Я говорю: «терпеть неудачу, терпеть неудачу рано» - и держать ваши исправления более приоритетными, чем функции.

Однако выбор также хорош - я не думаю, что один размер подходит для всех программ. По этой причине я использую несколько типов утверждений. Некоторые будут жить в релизе, некоторые нет. Я пишу много обнаружения ошибок, а также пишу много программ, критичных к производительности. Я не могу оставить кучу проверок диагностики и исправности в горячих путях сборок релизов.

К сожалению, это не может быть запоздалой мыслью (если, возможно, вы не готовы расставить приоритеты по качеству и тестировать в течение неограниченного времени). Если вы думаете об этом, единый / традиционный подход также не может быть запоздалой мыслью. Для любой модели лучше всего решить, будут ли утверждения или какие утверждения будут включены в выпуске до написания вашей программы.


Таким образом, основная общая форма модели двойного утверждения может выглядеть следующим образом:

#include <assert.h>

/*
  MONDebugAssert assertion is active in debug and disabled in release.
  Recommendation: Always define NDEBUG (or not) in your build settings, 
  and nowhere else.
*/
#if defined(NDEBUG)
    #define MONDebugAssert(e) ((void)0)
#else
    #define MONDebugAssert(e) \
        (__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)
#endif

/* MONAssert assertion is active at all times, including release builds. */
#define MONAssert(e) \
       (__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)

где __assert - обработчик утверждения платформы.

Затем используется:

MONDebugAssert(0); // << will fail in debug, and not in release.
MONAssert(0); // << will fail in any case

Конечно, достаточно легко адаптироваться к вашим потребностям или создать варианты, в которых предполагается, что self входит в область действия (например, NSAssert).

2 голосов
/ 13 декабря 2011

Всегда есть что-то лучше сделать в производственном коде, чем потерпеть неудачу при утверждении, но иногда компромисс менее урезан и просушен.

Хорошее время для утверждения: при продолжении работы уничтожаются пользовательские данные(«уже существует известный файл сохранения, и я обнаружил поврежденные структуры данных, если я перезаписываю хороший файл тем, что у меня есть, я его уничтожу»).Очевидно, что «лучший» вариант - не повредить данные в первую очередь.Во-вторых, лучше всего обнаружить поврежденные данные во время сохранения и сохранить в новый файл (он может быть загружаемым, или, возможно, то, что находится в нем, достаточно ценно для спасения героическими средствами).

Еще одно хорошее время для утверждения:когда вы знаете, что продолжение on завершится сбоем (передача NULL многим простым функциям C, вот-вот разделится на ноль ...).Утверждение будет нести более полезную информацию.Конечно, даже лучше не попасть в это состояние.На втором месте - прерывание операции, а не программы (лучше «Я не могу напечатать», чем «Я выбросил несохраненные данные, и, кстати, вы не можете печатать»).

Вы можете довольномногие всегда так ломают.Однако исправление ошибок довольно сложно, и обработка некоторых ошибок удвоит или ухудшит размер вашего кода для чего-то, что может никогда не произойти ... и тогда вам придется выяснить, как это проверить, и ...

... так что это компромисс.Что еще в вашей программе будет лучше, если вы экономите на восстановлении после ошибок?Будет ли лучше компенсировать дополнительные сбои?

1 голос
/ 13 марта 2015

Мои NSAssert сбои указывают на то, что что-то пошло не так, и дальнейшие действия приведут к неопределенному поведению и повреждению данных.Я не могу себе представить, почему люди попугаев отключают их в релизных сборках.

Если вы можете восстановиться после него, вы должны вместо этого использовать NSError.

...