Je dois poser cette question, car: La seule chose que je reconnais, c'est que si l'assertion échoue, l'application plante. Est-ce la raison pour laquelle utiliser NSAssert? Ou quel est l'avantage de celui-ci? Et est-il juste de mettre un NSAssert juste au-dessus de toute hypothèse que je fais dans le code, comme une fonction qui ne devrait jamais recevoir un -1 comme paramètre mais peut-être -0,9 ou -1,1?
Je ne peux pas vraiment parler à NSAssert, mais j'imagine que cela fonctionne de manière similaire à assert () de C.
assert () est utilisé pour appliquer un contrat sémantique dans votre code. Qu'est-ce que cela signifie, demandez-vous?
Eh bien, c'est comme vous l'avez dit: si vous avez une fonction qui ne devrait jamais recevoir de -1, vous pouvez demander à assert () d'appliquer cela:
Et maintenant, vous verrez quelque chose comme ça dans le journal des erreurs (ou STDERR):
Ainsi, non seulement il protège contre les entrées potentiellement mauvaises, mais il les enregistre de manière standard et utile.
Oh, et au moins en C, assert () était une macro, vous pouvez donc redéfinir assert () comme un no-op dans votre code de version. Je ne sais pas si c'est le cas avec NSAssert (ou même assert () plus), mais c'était assez utile de compiler ces vérifications.
la source
NSAssert
vous donne plus que simplement planter l'application. Il vous indique la classe, la méthode et la ligne où l'assertion s'est produite. Toutes les assertions peuvent également être facilement désactivées à l'aide de NS_BLOCK_ASSERTIONS. Le rendant ainsi plus adapté au débogage. D'un autre côté, lancer unNSException
ne fait que planter l'application. Il n'indique pas non plus l'emplacement de l'exception et ne peut pas non plus être désactivé si simplement. Voyez la différence dans les images ci-dessous.L'application se bloque car une assertion déclenche également une exception, comme l' indique la documentation NSAssert :
NSAssert:
NSException:
la source
NSException
offre de nombreuses possibilités de personnaliser la sortie qu'il renvoie via les paramètresreason
etuserInfo
. Il n'y a aucune raison pour laquelle vous ne pouvez pas ajouter le nom de classe, le sélecteur, les informations de ligne et tout ce que vous souhaitez ajouter pour aider au débogage. À mon humble avis, vous utilisez unNSAssert
à des fins de débogage pendant le développement, mais vous les désactivez pour l'expédition; vous lancez unNSException
si vous souhaitez laisser une assertion dans le code d'expédition.En dehors de ce que tout le monde a dit ci-dessus, le comportement par défaut de
NSAssert()
(contrairement à Cassert()
) est de lancer une exception, que vous pouvez attraper et gérer. Par exemple, Xcode fait cela.la source
Juste pour clarifier, comme quelqu'un l'a mentionné mais pas complètement expliqué, la raison d'avoir et d'utiliser des assertions au lieu de simplement créer du code personnalisé (faire des ifs et lever une exception pour de mauvaises données, par exemple) est que les assertions DEVRAIENT être désactivées pour les applications de production.
Lors du développement et du débogage, les assertions sont activées pour vous permettre de détecter les erreurs. Le programme s'arrête lorsqu'une assertion est évaluée comme fausse. Mais, lors de la compilation pour la production, le compilateur omet le code d'assertion et RENDENT VOTRE PROGRAMME PLUS RAPIDE. D'ici là, j'espère que vous avez corrigé tous les bogues. Dans le cas où votre programme a encore des bogues en production (lorsque les assertions sont désactivées et que le programme «saute» les assertions), votre programme finira probablement par planter à un autre moment.
De l'aide de NSAssert: "Les assertions sont désactivées si la macro de préprocesseur NS_BLOCK_ASSERTIONS est définie." Donc, mettez simplement la macro dans votre cible de distribution [uniquement].
la source
NSAssert
(et son équivalent stdlibassert
) sont de détecter les erreurs de programmation lors du développement. Vous ne devriez jamais avoir une assertion qui échoue dans une application de production (publiée). Vous pouvez donc affirmer que vous ne passez jamais un nombre négatif à une méthode qui nécessite un argument positif. Si l'assertion échoue pendant le test, vous avez un bogue. Si, cependant, la valeur transmise est entrée par l'utilisateur, vous devez valider correctement l'entrée plutôt que de vous fier à l'assertion en production (vous pouvez définir un #define pour les versions de version qui désactiveNSAssert*
.la source
Les assertions sont couramment utilisées pour imposer l'utilisation prévue d'une méthode ou d'un élément de logique particulier. Supposons que vous écriviez une méthode qui calcule la somme de deux entiers supérieurs à zéro. Afin de vous assurer que la méthode a toujours été utilisée comme prévu, vous mettriez probablement une affirmation qui teste cette condition.
Réponse courte: Ils imposent que votre code soit utilisé uniquement comme prévu.
la source
Il vaut la peine de souligner qu'en dehors de la vérification de l'exécution, la programmation d'assert est une fonction importante utilisée lorsque vous concevez votre code par contrat.
Vous trouverez ci-dessous plus d'informations sur l'assertion et la conception par contrat:
Assertion (développement logiciel)
Conception par contrat
Programmation avec assertions
Conception par contrat, par exemple [Broché]
la source
Pour répondre pleinement à sa question, le but de tout type d'affirmation est d'aider au débogage. Il est plus intéressant de détecter les erreurs à leur source, que de les détecter dans le débogueur lorsqu'elles provoquent des plantages.
Par exemple, vous pouvez transmettre une valeur à une fonction qui attend des valeurs dans une certaine plage. La fonction peut stocker la valeur pour une utilisation ultérieure et, lors d'une utilisation ultérieure, l'application se bloque. La pile d'appels vue dans ce scénario n'afficherait pas la source de la valeur incorrecte. Il est préférable d'attraper la mauvaise valeur au fur et à mesure qu'elle entre pour savoir qui passe la mauvaise valeur et pourquoi.
la source
NSAssert
faire planter l'application lorsqu'elle correspond à la condition. S'il ne correspond pas à la condition, les instructions suivantes seront exécutées. Recherchez l'EX ci-dessous:Je viens de créer une application pour tester quelle est la tâche de
NSAssert
:dans mon code, l'application ne plantera pas.Et le cas de test est:
anNum
> = 2 -> L'application ne plantera pas et vous pouvez voir la chaîne du journal: "Cette instruction s'exécutera quand unNum <2" dans la fenêtre de la console du journal outPutanNum
<2 -> L'application plantera et vous ne pouvez pas voir la chaîne de journal: "Cette instruction s'exécutera quand anNum <2"la source