一.NSParameterAssert官方解釋
Assertions evaluate a condition and, if the condition evaluates to false, call the assertion handler for the current thread, passing it a format string and a variable number of arguments. Each thread has its own assertion handler, which is an object of classNSAssertionHandler.
When invoked, an assertion handler prints an error message that includes method and class names (or the function name). It then raises anNSInternalInconsistencyException exception.
斷言評(píng)估一個(gè)條件,如果條件為 false 蒂胞,調(diào)用當(dāng)前線程的斷點(diǎn)句柄岳瞭。每一個(gè)線程有它自已的斷點(diǎn)句柄蚊锹,它是一個(gè) NSAsserttionHandler 類的對(duì)象牡昆。當(dāng)被調(diào)用時(shí)丢烘,斷言句柄打印一個(gè)錯(cuò)誤信息,該條信息中包含了方法名播瞳、類名或函數(shù)名赢乓。然后,它就拋出一個(gè) NSInternalInconsistencyException 異常牌芋。
This macro validates a parameter for an Objective-C method. Simply provide the parameter as the condition argument. The macro evaluates the parameter and, if it is false, it logs an error message that includes the parameter and then raises an exception.
這個(gè)宏用于確認(rèn)一個(gè) Objective-C 的方法的有效性肯夏。簡單提供參數(shù)作為條件就行驯击。該宏評(píng)估這個(gè)參數(shù)耐亏,如果為 false 碟贾,它就打印一個(gè)錯(cuò)誤日志信息轨域,該信息包含了參數(shù)并且拋出一個(gè)異常干发。
Assertions are disabled if the preprocessor macro NS_BLOCK_ASSERTIONS is defined. All assertion macros return void.
如果定義了預(yù)處理宏 NS_BLOCK_ASSERTIONS 斷言就被禁止了枉长。所有的斷點(diǎn)宏都返回 void必峰。
斷言是從經(jīng)典的邏輯學(xué)中借用過來的概念。在邏輯學(xué)中凭需,斷言是對(duì)已經(jīng)證明過的命題的陳述。在編程中粒蜈,斷言是指程序員所做出的關(guān)于應(yīng)用程序在它們所聲明的地方的一些假設(shè)枯怖。
當(dāng)用于先驗(yàn)條件和后驗(yàn)條件能力范圍內(nèi)時(shí),斷言形成了一種契約,它描述了代碼在執(zhí)行一個(gè)方法或函數(shù)的開始和結(jié)束時(shí)的狀態(tài)的期望塘淑。斷言也能用于加強(qiáng)運(yùn)行時(shí)的條件槐沼,為了當(dāng)先驗(yàn)條件失敗時(shí)阻止程序運(yùn)行捌治。
斷言與單元測試有些類似肖油,它們都定義了代碼將會(huì)運(yùn)行的期望結(jié)果森枪。與單元測試不同的是,斷言存在于程序本身,并且因此被限定在程序的上下文中筋遭。因?yàn)閱卧獪y試是完全獨(dú)立的暴拄,它們完全有能力通過使用像方法樁和模擬對(duì)象等工具隔離并且單獨(dú)測試特定的行為乖篷。開發(fā)者應(yīng)當(dāng)在應(yīng)該程序中結(jié)合使用合理數(shù)量的斷言和單元測試來測試和定義應(yīng)用程序行為踏施。
二.原理
- Objective-C 用一個(gè)面向?qū)ο蟮耐緩交旌狭?C 語言風(fēng)格的斷言宏定義來注入和處理斷言失敗罕邀。即:
NSAssertionHandler
: - 每個(gè)線程擁有它自己的斷言處理器诉探,它是 NSAssertionHandler 類的實(shí)例對(duì)象肾胯。當(dāng)被調(diào)用時(shí)敬肚,一個(gè)斷言處理器打印一條包含方法和類名(或者函數(shù)名)的錯(cuò)誤信息艳馒。然后它拋出一個(gè)
NSInternalInconsistencyException
異常弄慰。
三.延伸
基礎(chǔ)類庫中定義了兩套斷言宏:
NSAssert / NSCAssert
NSParameterAssert / NSCParameterAssert
基礎(chǔ)類庫從語義學(xué)上和功能性上使斷言處理器的 API 在兩個(gè)方面區(qū)別開來陆爽。
1.第一個(gè)區(qū)別在于一般斷言(NSAssert)和參數(shù)化斷言(NSParameterAssert)慌闭。方法或函數(shù)應(yīng)當(dāng)在代碼最開始處使用 NSParameterAssert / NSCParameterAssert 來強(qiáng)制輸入的值滿足先驗(yàn)條件驴剔,這是一條金科玉律仔拟;其他情況下使用 NSAssert / NSCAssert利花。
-
2.第二個(gè)區(qū)別在于 C 和 Objective-C 的斷言:NSAssert 應(yīng)當(dāng)只用于 Objective-C 環(huán)境中(即方法實(shí)現(xiàn)中),而 NSCAssert 應(yīng)當(dāng)只用于 C 環(huán)境中(即函數(shù)中)
- 當(dāng) NSAssert 或 NSParameterAssert 的條件不滿足時(shí),斷言處理器會(huì)調(diào)用
-handleFailureInMethod:object:file:lineNumber:description:
方法权薯。 - 當(dāng) NSCAssert 或 NSCParameterAssert 的條件不滿足時(shí)盟蚣,斷言處理器會(huì)調(diào)用
-handleFailureInFunction:file:lineNumber:description:
方法屎开。
- 當(dāng) NSAssert 或 NSParameterAssert 的條件不滿足時(shí),斷言處理器會(huì)調(diào)用
值得注意的是,從 Xcode 4.2 開始蔼两,發(fā)布構(gòu)建默認(rèn)關(guān)閉了斷言额划,它是通過定義 NS_BLOCK_ASSERTIONS 宏實(shí)現(xiàn)的。也就是說茁瘦,當(dāng)編譯發(fā)布版時(shí)甜熔,任何調(diào)用 NSAssert 等的地方都被有效的移除了腔稀。
四.斷言代碼示例
方法一.一般斷言,我們可以這么寫
if (_menuController == nil || _mainController == nil) {
@throw [NSException exceptionWithName: @"LXDNullInstanceException" reason: @"you can not slide view when one or more of menu view and main view is nil" userInfo: nil];
}
// 如果其中一個(gè)條件成立,程序崩潰,報(bào)下面的錯(cuò)
// *** Terminating app due to uncaught exception 'LXDNullInstanceException',
reason: 'you can not slide view when one or more of menu view and main view is nil'
方法二:NSAssert
NSAssert(_menuController != nil , @"you can not slide view when one or more of menu view and main view is nil" );
// 方法名 m:118行 報(bào)錯(cuò)描述
// *** Assertion failure in -[LXDSlideManager open], /Users/mac/Downloads/LXDSlideManager.m:118
2016-05-29 17:47:53.655
LXDSlideMenuObjectiveC[77358:4074358]
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'you can not slide view when one or more of menu view and main view is nil'
方法三: NSParameterAssert
NSParameterAssert((_menuController != nil));
// 方法名 m:118行 報(bào)錯(cuò)描述
// *** Assertion failure in -[LXDSlideManager open], /Users/mac/Downloads/LXDSlideManager.m:118
2016-05-29 17:47:53.655
LXDSlideMenuObjectiveC[77358:4074358]
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'you can not slide view when one or more of menu view and main view is nil'
注意條件書寫不支持邏輯或語法
// 錯(cuò)誤寫法,不支持邏輯或語法
NSParameterAssert(_menuController != nil || _mainController != nil);
// 錯(cuò)誤寫法,不支持邏輯或語法
NSAssert(_menuController != nil || _mainController != nil , @"you can not slide view when one or more of menu view and main view is nil" );