Tengo que preguntar esto, porque: Lo único que reconozco es que si la afirmación falla, la aplicación falla. ¿Es esa la razón por la cual usar NSAssert? ¿O qué más es el beneficio de esto? ¿Y es correcto poner un NSAssert justo por encima de cualquier suposición que haga en el código, como una función que nunca debería recibir un -1 como parámetro, pero puede un -0.9 o -1.1?
155
Realmente no puedo hablar con NSAssert, pero imagino que funciona de manera similar a la afirmación de C ().
afirmar () se utiliza para hacer cumplir un contrato semántico en su código. ¿Qué significa eso, preguntas?
Bueno, es como dijiste: si tienes una función que nunca debería recibir un -1, puedes hacer valer aserción ():
Y ahora verá algo como esto en el registro de errores (o STDERR):
Por lo tanto, no solo protege contra entradas potencialmente malas, sino que las registra de una manera útil y estándar.
Ah, y al menos en C afirmar () era una macro, por lo que podría redefinir afirmar () como no operativo en su código de lanzamiento. No sé si ese es el caso con NSAssert (o incluso afirmar () más), pero fue bastante útil compilar esos controles.
fuente
NSAssert
te da más que simplemente bloquear la aplicación. Le indica la clase, el método y la línea donde ocurrió la aserción. Todas las aserciones también se pueden desactivar fácilmente utilizando NS_BLOCK_ASSERTIONS. Por lo tanto, es más adecuado para la depuración. Por otro lado, arrojar unNSException
solo bloquea la aplicación. Tampoco informa sobre la ubicación de la excepción, ni puede deshabilitarse de manera tan simple. Vea la diferencia en las imágenes a continuación.La aplicación se bloquea porque una aserción también genera una excepción, ya que la documentación de NSAssert establece:
NSAssert:
NSException:
fuente
NSException
ofrece muchas oportunidades para personalizar la salida que devuelve a través de los parámetrosreason
yuserInfo
. No hay ninguna razón por la que no pueda agregar el nombre de la clase, el selector, la información de línea y cualquier otra cosa que desee agregar para ayudar con la depuración. En mi humilde opinión, se utilizaNSAssert
para fines de depuración durante el desarrollo, pero los deshabilita para enviar; arroja unNSException
si desea dejar una afirmación en el código de envío.Además de lo que todos dijeron anteriormente, el comportamiento predeterminado de
NSAssert()
(a diferencia de Cassert()
) es lanzar una excepción, que puede atrapar y manejar. Por ejemplo, Xcode hace esto.fuente
Solo para aclarar, como alguien mencionó pero no explicó por completo, la razón para tener y usar afirmaciones en lugar de simplemente crear código personalizado (hacer ifs y generar una excepción para datos incorrectos, por ejemplo) es que las afirmaciones DEBEN estar deshabilitadas para las aplicaciones de producción.
Durante el desarrollo y la depuración, las afirmaciones están habilitadas para que pueda detectar errores. El programa se detendrá cuando una afirmación se evalúe como falsa. Pero, cuando compila para la producción, el compilador omite el código de aserción y en realidad HACE QUE SU PROGRAMA SE EJECUTE MÁS RÁPIDO. Para entonces, con suerte, ya ha solucionado todos los errores. En caso de que su programa todavía tenga errores durante la producción (cuando las aserciones están deshabilitadas y el programa "omite" las aserciones), su programa probablemente terminará fallando en algún otro momento.
De la ayuda de NSAssert: "Las afirmaciones se deshabilitan si se define la macro del preprocesador NS_BLOCK_ASSERTIONS". Entonces, solo coloque la macro en su objetivo de distribución [solo].
fuente
NSAssert
(y su equivalente stdlibassert
) son para detectar errores de programación durante el desarrollo. Nunca debe tener una afirmación que falle en una aplicación de producción (lanzada). Por lo tanto, puede afirmar que nunca pasa un número negativo a un método que requiere un argumento positivo. Si la afirmación falla alguna vez durante la prueba, tiene un error. Sin embargo, si el usuario ingresa el valor pasado, debe realizar una validación adecuada de la entrada en lugar de confiar en la afirmación en producción (puede establecer un #definir para las compilaciones de lanzamiento que deshabilita)NSAssert*
.fuente
Las aserciones se usan comúnmente para imponer el uso previsto de un método particular o una pieza de lógica. Digamos que estaba escribiendo un método que calcula la suma de dos enteros mayores que cero. Con el fin de asegurarse de que el método siempre se usó según lo previsto, es probable que ponga una afirmación que pruebe esa condición.
Respuesta corta: exigen que su código se use solo según lo previsto.
fuente
Vale la pena señalar que, aparte de la verificación del tiempo de ejecución, la programación de afirmación es una instalación importante que se utiliza cuando diseña su código por contrato.
Más información sobre el tema de la afirmación y el diseño por contrato se puede encontrar a continuación:
Afirmación (desarrollo de software)
Diseño por contrato
Programación con aserciones
Diseño por contrato, por ejemplo [Paperback]
fuente
Para responder completamente a su pregunta, el objetivo de cualquier tipo de afirmación es ayudar a la depuración. Es más valioso detectar errores en su origen y luego detectarlos en el depurador cuando provocan bloqueos.
Por ejemplo, puede pasar un valor a una función que espera valores en un cierto rango. La función puede almacenar el valor para su uso posterior, y en el uso posterior, la aplicación se bloquea. La pila de llamadas que se ve en este escenario no muestra la fuente del valor incorrecto. Es mejor detectar el valor negativo a medida que entra para averiguar quién está pasando el valor negativo y por qué.
fuente
NSAssert
hacer que la aplicación se bloquee cuando coincida con la condición. Si no coincide con la condición, se ejecutarán las siguientes declaraciones. Busque el EX a continuación:Acabo de crear una aplicación para probar cuál es la tarea
NSAssert
:en mi código, la aplicación no se bloqueará. Y el caso de prueba es:
anNum
> = 2 -> La aplicación no se bloqueará y puede ver la cadena de registro: "Esta instrucción se ejecutará cuando anNum <2" en la ventana de la consola de registro de salidaanNum
<2 -> La aplicación se bloqueará y no podrá ver la cadena de registro: "Esta instrucción se ejecutará cuando anNum <2"fuente