Eu tenho que perguntar isso porque: A única coisa que reconheço é que, se a afirmação falhar, o aplicativo trava. É por isso que usar o NSAssert? Ou qual é o benefício disso? E é correto colocar um NSAssert acima de qualquer suposição que eu faça no código, como uma função que nunca deve receber um -1 como parâmetro, mas pode -0,9 ou -1,1?
155
Eu realmente não posso falar com a NSAssert, mas imagino que funcione de maneira semelhante à afirmação de C ().
assert () é usado para impor um contrato semântico no seu código. O que significa isso, você pergunta?
Bem, é como você disse: se você tem uma função que nunca deve receber um -1, pode ter o assert () que impõe isso:
E agora você verá algo assim no log de erros (ou STDERR):
Portanto, ele não apenas protege contra entradas potencialmente ruins, como as registra de maneira útil e padrão.
Ah, e pelo menos em C assert () havia uma macro, para que você pudesse redefinir assert () como não operacional no seu código de lançamento. Não sei se esse é o caso do NSAssert (ou até mesmo assert ()), mas foi bastante útil compilar essas verificações.
fonte
NSAssert
oferece mais do que apenas travar o aplicativo. Indica a classe, o método e a linha em que a afirmação ocorreu. Todas as asserções também podem ser facilmente desativadas usando NS_BLOCK_ASSERTIONS. Assim, tornando-o mais adequado para depuração. Por outro lado, jogar umNSException
único trava o aplicativo. Ele também não informa sobre a localização da exceção, nem pode ser desativado de maneira simples. Veja a diferença nas imagens abaixo.O aplicativo falha porque uma asserção também gera uma exceção, conforme a documentação da NSAssert afirma:
NSAssert:
NSException:
fonte
NSException
fornece muitas oportunidades para personalizar a saída que retorna através dos parâmetrosreason
euserInfo
. Não há motivo para você não poder adicionar o nome da classe, o seletor, as informações da linha e qualquer outra coisa que queira adicionar para ajudar na depuração. IMHO, você usa umNSAssert
para fins de depuração durante o desenvolvimento, mas os desabilita para enviar; você lança umNSException
se quiser deixar uma afirmação no código de remessa.Além do que todos disseram acima, o comportamento padrão de
NSAssert()
(ao contrário dos C'sassert()
) é lançar uma exceção que você pode capturar e manipular. Por exemplo, o Xcode faz isso.fonte
Apenas para esclarecer, como alguém mencionado, mas não totalmente explicado, a razão para ter e usar afirmações em vez de apenas criar código personalizado (fazendo ifs e criando uma exceção para dados ruins, por exemplo) é que afirma que DEVE ser desativado para aplicativos de produção.
Durante o desenvolvimento e a depuração, as declarações são ativadas para você detectar erros. O programa será interrompido quando uma declaração for avaliada como falsa. Porém, ao compilar para produção, o compilador omite o código de asserção e, na verdade, REALIZE SEU PROGRAMA MAIS RÁPIDO. Até então, espero que você tenha corrigido todos os erros. Caso seu programa ainda tenha erros durante a produção (quando as asserções estão desabilitadas e o programa "pula" as asserções)), é provável que seu programa acabe travando em algum outro momento.
Da ajuda do NSAssert: "As asserções serão desabilitadas se a macro NS_BLOCK_ASSERTIONS do pré-processador estiver definida." Então, basta colocar a macro no seu destino de distribuição [apenas].
fonte
NSAssert
(e seu equivalente stdlibassert
) são para detectar erros de programação durante o desenvolvimento. Você nunca deve ter uma asserção que falha em um aplicativo de produção (liberado). Portanto, você pode afirmar que nunca passa um número negativo para um método que requer um argumento positivo. Se a afirmação falhar durante o teste, você tem um erro. Se, no entanto, o valor passado for inserido pelo usuário, você precisará fazer a validação adequada da entrada, em vez de confiar na asserção em produção (você pode definir um #define para builds de release que desabilitaNSAssert*
.fonte
As asserções são comumente usadas para impor o uso pretendido de um método ou pedaço de lógica específico. Digamos que você estivesse escrevendo um método que calcula a soma de dois maiores que zero números inteiros. Para garantir que o método sempre fosse usado como pretendido, você provavelmente colocaria uma afirmação que testa essa condição.
Resposta curta: eles reforçam que seu código é usado apenas como pretendido.
fonte
Vale ressaltar que, além da verificação do tempo de execução, afirmar que a programação é um recurso importante usado quando você cria seu código por contrato.
Mais informações sobre asserção e design por contrato podem ser encontradas abaixo:
Asserção (desenvolvimento de software)
Design por contrato
Programando com asserções
Design by Contract, by Example [Brochura]
fonte
Para responder completamente à sua pergunta, o objetivo de qualquer tipo de afirmação é ajudar na depuração. É mais valioso capturar erros na origem e capturá-los no depurador quando eles causam falhas.
Por exemplo, você pode passar um valor para uma função que espera valores em um determinado intervalo. A função pode armazenar o valor para uso posterior e, posteriormente, o aplicativo trava. A pilha de chamadas vista neste cenário não mostraria a origem do valor incorreto. É melhor pegar o valor ruim, pois ele chega para descobrir quem está passando o valor ruim e por quê.
fonte
NSAssert
faça com que o aplicativo falhe quando corresponder à condição. Se não corresponder à condição, as próximas instruções serão executadas. Procure o EX abaixo:Acabei de criar um aplicativo para testar qual é a tarefa
NSAssert
:no meu código, o aplicativo não trava. E o caso de teste é:
anNum
> = 2 -> O aplicativo não falha e você pode ver a sequência de log: "Esta instrução será executada quando anNum <2" na janela do console de log outPutanNum
<2 -> O aplicativo falhará e você não poderá ver a sequência de log: "Esta instrução será executada quando anNum <2"fonte