斷言(assert) 是指在開發過程是使用的,讓程序在運行時進行自檢的代碼 (通常是一個子程序或宏). 斷言為真,則表明程序運行正常,而斷言為假,則意味著它已經在代碼中發現了意料之外的錯誤.斷言對于大型的復雜程序或可靠性要求極高的程序來說尤其有用.
下面是<<代碼大全>>中的防御式編程中的有關斷言的指導性意見:
1.用錯誤處理代碼來處理預期會發生的狀況,用斷言來處理所不應該發生的狀況
2.避免把需要執行的代碼放到斷言中
3.用斷言來注解并驗證前條件和后條件
4.對于高健壯性的代碼,應該先使用斷言再處理錯誤
對來源于內部系統的可靠的數據使用斷言,而不要對外部不可靠的數據使用斷言,對于外部不可靠數據,應該使用錯誤處理代碼。斷言可以看成可執行的注釋。
系統外部的數據(用戶輸入,文件,網絡讀取等等)都是不可信的,需要嚴格檢查(通常是錯誤處理)才能放行到系統內部,這相當于一個守衛。而對于系統內部的交互(比如子程序調用),如果每次也都去處理輸入的數據,也就相當于系統沒有可信的邊界了,會讓代碼變的臃腫復雜;而事實上,在系統內部,傳遞給子程序預期的恰當數據應該是調用者的責任,系統內的調用者應該確保傳遞給子程序的數據是恰當可以正常工作的。這樣一來,就隔離了不可靠的外部環境和可靠的系統內部環境,降低復雜度。
但是在開發階段,代碼極可能包含缺陷,也許是處理外部數據的程序考慮的不夠周全,也許是調用系統內部子程序的代碼存在錯誤,造成子程序調用失敗。這個時候,斷言就可以發揮作用,用來確診到底是那部分出現了問題而導致子程序調用失敗。在清理了所有缺陷之后,內外有別的信用體系就建立起來。等到發行版時候,這些斷言就應該沒有存在必要。
在iOS開發中,可以使用宏NSAssert()在程序中進行斷言處理。NSAssert()使用正確,可以幫助開發者盡快定位bug。開發者沒有必要在應用程序的每個版本中都進行斷言檢查,這是因為大多數項目都是有兩個版本:Debug版和Release版。在Debug版中,開發者希望所有的斷言都檢查到,而在Release版中,往往都是禁用斷言檢查的。設置Release版本中禁用斷言的方法如下:
在Build Settings菜單,找到Preprocessor Macros項,Preprocessor Macros項下面有一個選擇,用于程序生成配置:Debug版和Release版。選擇 Release項,設置NS_BLOCK_ASSERTIONS,不進行斷言檢查。如下圖所示。
下面,我們在一個 打印名字的函數里面,加入斷言,以使程序在發現輸入的名字為空時,拋出異常。
-?(void)printMyName:(NSString*)myName
{
NSAssert(myName?!=nil,@"名字不能為空!");
NSLog(@"My?name?is?%@.",myName);
}
當傳給函數的參數(myName)為空時,斷言將被執行,程序Crash,并打印出斷言中的描述信息。本例中,在控制臺打印出了如下的日志:
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: '名字不能為空!'
斷言告訴我們,傳入的參數不能為空,通過這個報錯很容易就能確定錯誤發生的原因及位置。
如果,我們傳入非空的參數,則程序會正確打印出傳入的名字:
My name is UnivCore.
下面,我們將測試程序設置為Release版本,依據之前的設定,即使當傳入的參數為空時,斷言也不會被執行。設置為Release版本的方法如下:
依次點擊Product->Scheme->Edit Scheme...(也可以直接按快捷鍵command + shift + ,),選擇Run 項,然后在Info面板上修改Build Configuration為Release,就可以將當前的生成配置改為Release。然后,生成并運行程序,就會生成Release版本的程序。注意,對于Archive 項,默認的生成配置就是Release。
此時,我們再運行程序,程序會打印如下語句:
My name is (null).
這說明,斷言代碼沒有運行。本文出處:blog.csdn.net/univcore/article/details/16859263