斷言(assertion)是指在開發(fā)期間使用的、讓程序在運(yùn)行時(shí)進(jìn)行自檢的代碼(通常是一個(gè)子程序或宏)割坠。斷言為真齐帚,則表明程序運(yùn)行正常,而斷言為假彼哼,則意味著它已經(jīng)在代碼中發(fā)現(xiàn)了意料之外的錯(cuò)誤对妄。斷言對(duì)于大型的復(fù)雜程序或可靠性要求極高的程序來(lái)說尤其有用。
在開發(fā)階段敢朱,代碼極可能包含缺陷饥伊,也許是處理外部數(shù)據(jù)的程序考慮的不夠周全,也許是調(diào)用系統(tǒng)內(nèi)部子程序的代碼存在錯(cuò)誤蔫饰,造成子程序調(diào)用失敗琅豆。這個(gè)時(shí)候,斷言就可以發(fā)揮作用篓吁,用來(lái)確診到底是那部分出現(xiàn)了問題而導(dǎo)致子程序調(diào)用失敗茫因。在清理了所有缺陷之后,內(nèi)外有別的信用體系就建立起來(lái)杖剪。等到發(fā)行版時(shí)候冻押,這些斷言就應(yīng)該沒有存在必要。
在iOS開發(fā)中盛嘿,可以使用宏NSAssert()在程序中進(jìn)行斷言處理洛巢。NSAssert()使用正確,可以幫助開發(fā)者盡快定位bug次兆。開發(fā)者沒有必要在應(yīng)用程序的每個(gè)版本中都進(jìn)行斷言檢查稿茉,這是因?yàn)榇蠖鄶?shù)項(xiàng)目都是有兩個(gè)版本:Debug版和Release版。在Debug版中芥炭,開發(fā)者希望所有的斷言都檢查到漓库,而在Release版中,往往都是禁用斷言檢查的园蝠。設(shè)置Release版本中禁用斷言的方法如下:
在Build Settings菜單渺蒿,找到Preprocessor Macros項(xiàng),Preprocessor Macros項(xiàng)下面有一個(gè)選擇彪薛,用于程序生成配置:Debug版和Release版茂装。選擇 Release項(xiàng)怠蹂,設(shè)置NS_BLOCK_ASSERTIONS
,不進(jìn)行斷言檢查少态。如下圖所示褥蚯。
下面,我們?cè)谝粋€(gè) 打印名字的函數(shù)里面况增,加入斷言赞庶,以使程序在發(fā)現(xiàn)輸入的名字為空時(shí),拋出異常澳骤。
- (void)printMyName:(NSString *)myName
{
NSAssert(myName != nil, @"名字不能為空歧强!");
NSLog(@"My name is %@.",myName);
}
當(dāng)傳給函數(shù)的參數(shù)(myName)為空時(shí),斷言將被執(zhí)行为肮,程序Crash摊册,并打印出斷言中的描述信息。本例中颊艳,在控制臺(tái)打印出了如下的日志:
NSAssert[1268:a0b] *** Assertion failure in -[ViewController printMyName:]
NSAssert/NSAssert/ViewController.m:38
2013-11-21 13:56:01.927 NSAssert[1268:a0b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '名字不能為空茅特!'
斷言告訴我們,傳入的參數(shù)不能為空棋枕,通過這個(gè)報(bào)錯(cuò)很容易就能確定錯(cuò)誤發(fā)生的原因及位置白修。
如果,我們傳入非空的參數(shù)重斑,則程序會(huì)正確打印出傳入的名字:
My name is UnivCore.
下面兵睛,我們將測(cè)試程序設(shè)置為Release版本,依據(jù)之前的設(shè)定窥浪,即使當(dāng)傳入的參數(shù)為空時(shí)祖很,斷言也不會(huì)被執(zhí)行。設(shè)置為Release版本的方法如下:
依次點(diǎn)擊Product->Scheme->Edit Scheme...(也可以直接按快捷鍵command + shift + ,)漾脂,選擇Run 項(xiàng)假颇,然后在Info面板上修改Build Configuration為Release,就可以將當(dāng)前的生成配置改為Release骨稿。然后笨鸡,生成并運(yùn)行程序,就會(huì)生成Release版本的程序啊终。注意镜豹,對(duì)于Archive 項(xiàng),默認(rèn)的生成配置就是Release蓝牲。
此時(shí),我們?cè)龠\(yùn)行程序泰讽,程序會(huì)打印如下語(yǔ)句:
My name is (null).
這說明例衍,斷言代碼沒有運(yùn)行昔期。