Какой смысл NSAssert, на самом деле?

Я должен спросить это, потому что: единственное, что я признаю, это то, что если утверждение терпит неудачу, приложение падает. Это причина, почему использовать NSAssert? Или в чем еще польза от этого? И правильно ли ставить NSAssert чуть выше любого предположения, которое я делаю в коде, как функция, которая никогда не должна получать -1 как param, но может -0.9 или -1.1?

10 ответов


Assert - убедиться, что значение является тем, чем оно должно быть. Если утверждение не выполняется, это означает, что что-то пошло не так и приложение завершает работу. Одна из причин, чтобы использовать assert будет, если у вас есть некоторые функции, которые не ведут себя или создаст очень плохие побочные эффекты, если один из параметров передан не точно какое-то значение (или диапазон значений) вы можете положить утверждать, чтобы убедиться, что значение-это то, что вы ожидаете, и если это не так, что-то не то, а так приложение завершает работу. Assert может быть очень полезен для отладки / модульного тестирования, а также Когда вы предоставляете фреймворки, чтобы остановить пользователей от "злых" вещей.


Я не могу говорить с NSAssert, но я полагаю, что он работает аналогично assert () C.

assert () используется для обеспечения семантического контракта в коде. Что это значит, спросите вы?

Ну, как вы сказали: если у вас есть функция, которая никогда не должна получать -1, вы можете иметь assert () принудительно, что:

void gimme_positive_ints(int i) {
  assert(i > 0);
}

и теперь вы увидите что-то вроде этого в журнале ошибок (или STDERR):

Assertion i > 0 failed: file example.c, line 2

Так это не только safe-защитите от потенциально плохих входов, но он регистрирует их полезным стандартным способом.

О, и, по крайней мере, в C assert() был макросом, поэтому вы можете переопределить assert() как no-op в своем коде выпуска. Я не знаю, так ли обстоит дело с NSAssert (или даже assert() больше), но было довольно полезно скомпилировать эти проверки.


помимо того, что все сказали выше, поведение по умолчанию NSAssert() (в отличие от C assert()) - это исключение, которое можно перехватить и обработать. Например, Xcode делает это.


NSAssert дает вам больше, чем просто сбой приложения. Он сообщает вам класс, метод и строку, в которой произошло утверждение. Все утверждения также можно легко деактивировать с помощью NS_BLOCK_ASSERTIONS. Таким образом, это делает его более подходящим для отладки. С другой стороны, бросая NSException только сбой приложения. Он также не говорит о местоположении исключения, и его нельзя отключить так просто. Увидеть разницу в изображениях под.

приложение аварийно завершает работу, потому что утверждение также вызывает исключение, как документация NSAssert гласит:

при вызове обработчик утверждений печатает сообщение об ошибке, которое включает имена метода и класса (или имя функции). Это тогда поднимает NSInternalInconsistencyException исключение.

NSAssert:

Logs after an assertion

NSException:

Logs after an exception


просто чтобы уточнить, как кто-то упомянул, но не полностью объяснил, причина наличия и использования утверждений вместо того, чтобы просто создавать пользовательский код (например, делать ifs и вызывать исключение для плохих данных) заключается в том, что утверждения должны быть отключены для производственных приложений.

при разработке и отладке утверждения включены для вас, чтобы поймать ошибки. Программа остановится, когда assert оценивается как false. Но при компиляции для производства компилятор опускает код утверждения и на самом деле сделать вашу программу работать быстрее. К тому времени, надеюсь, вы исправите все ошибки. Если ваша программа все еще имеет ошибки во время работы (когда утверждения отключены и программа "пропускает" утверждения), ваша программа, вероятно, в конечном итоге сбой в какой-то другой момент.

из справки NSAssert: "утверждения отключаются, если определен макрос препроцессора NS_BLOCK_ASSERTIONS." Итак, просто поместите макрос в цель распространения [только].


NSAssert (и его эквивалент stdlib assert) для обнаружения ошибок программирования во время разработки. У вас никогда не должно быть утверждения, которое не выполняется в производственном (выпущенном) приложении. Таким образом, вы можете утверждать, что никогда не передаете отрицательное число методу, требующему положительного аргумента. Если утверждение всегда терпит неудачу во время тестирования, у вас есть ошибка. Если, однако, переданное значение введено пользователем, необходимо выполнить правильную проверку входных данных, а не полагаться на утверждение в производстве (вы можете установить #define для сборок выпуска, которые отключают NSAssert*.


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

короткий ответ: они обеспечивают, чтобы ваш код использовался только по назначению.


стоит отметить, что помимо проверки времени выполнения, assert programming является важным средством, используемым при разработке кода по контракту.

более подробную информацию по вопросу утверждения и проектирования по контракту можно найти ниже:

утверждение (разработка программного обеспечения)

оформление по договору

Программирование С Утверждениями

проектирование по контракту, на примере [В мягкой обложке]


чтобы полностью ответить на его вопрос, точка любого типа assert должна помочь отладке. Более ценно поймать ошибки в их источнике, а затем поймать их в отладчике, когда они вызывают сбои.

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


NSAssert сделать приложение аварии, когда он совпадает с условием. Если не соответствует условию, будут выполняться следующие операторы. Посмотрите на EX ниже:

Я просто создаю приложение, чтобы проверить, что такое задача NSAssert - это:

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self testingFunction:2];
}

-(void)testingFunction: (int)anNum{
    // if anNum < 2 -> the app will crash
    // and the NSLog statement will not execute
    // that mean you cannot see the string: "This statement will execute when anNum < 2"
    // into the log console window of Xcode
    NSAssert(anNum >= 2, @"number you enter less than 2");
    // If anNum >= 2 -> the app will not crash and the below 
    // statement will execute
    NSLog(@"This statement will execute when anNum < 2");
}

в мой код приложение не будет сбой.И тестовый пример:

  • anNum >= 2 -> приложение не рухнет, и вы можете увидеть строку журнала: "эта инструкция будет выполняться, когда anNum
  • anNum NSAssert приложение будет сбой, и вы не можете увидеть строку журнала: "это заявление будет выполняться, когда anNum