iOS中的斷言

NSAssert

這個應該都比較熟悉,他的名字叫做“斷言”。斷言(assertion)是指在開發期間使用的、讓程序在運行時進行自檢的代碼(通常是一個子程序或宏)。斷言為真,則表明程序運行正常,而斷言為假,則意味著它已經在代碼中發現了意料之外的錯誤。斷言對于大型的復雜程序或可靠性要求極高的程序來說尤其有用。而當斷言為假的時候,幾乎所有的系統的處理策略都是,讓程序死掉,即Crash掉。方便你知道,程序出現了問題。

斷言其實是“防御式編程”的常用的手段。防御式編程的主要思想是:子程序應該不因傳入錯誤數據而被破壞,哪怕是由其他子程序產生的錯誤數據。這種思想是將可能出現的錯誤造成的影響控制在有限的范圍內。斷言能夠有效的保證數據的正確性,防止因為臟數據讓整個程序運行在不穩定的狀態下面。

關于如何使用斷言,還是參考《代碼大全2》中“防御式編程”一章。這里簡單的做了一點摘錄,概括其大意:

用錯誤處理代碼來處理預期會發生的狀況,用斷言來處理絕不應該發生的狀況。

  • 避免把需要執行的代碼放到斷言中
  • 用斷言來注解并驗證前條件和后條件
  • 對于高健壯性的代碼,應該先使用斷言再處理錯誤
  • 對來源于內部系統的可靠的數據使用斷言,而不要對外部不可靠的數據使用斷言,對于外部不可靠數據,應該使用錯誤處理代碼。 而在IOS編程中,我們可以使用NSAssert來處理斷言。比如:

- (void)printMyName:(NSString *)myName { NSAssert(myName == nil, @"名字不能為空!"); NSLog(@"My name is %@.",myName); }

我們驗證myName的安全性,需要保證其不能為空。NSAssert會檢查其內部的表達式的值,如果為假則繼續執行程序,如果不為假讓程序Crash掉。

每一個線程都有它自己的斷言捕獲器(一個NSAssertionHanlder的實例),當斷言發生時,捕獲器會打印斷言信息和當前的類名、方法名等信息。然后拋出一個NSInternalInconsistencyException異常讓整個程序Crash掉。并且在當前線程的斷言捕獲器中執行handleFailureInMethod:object:file:lineNumber:description:以上述信息為輸出。

當時,當程序發布的時候,不能把斷言帶入安裝包,你不想讓程序在用戶機器上Crash掉吧。打開和關閉斷言可以在項目設置中設置assert ,在release版本中設置了NS_BLOCK_ASSERTIONS之后斷言失效。

盡可能不要用Try-Catch

并不是說Try-Catch這樣的異常處理機制不好。而是,很多人在編程中,錯誤了使用了Try-Catch,把異常處理機制用在了核心邏輯中。把其當成了一個變種的GOTO使用。把大量的邏輯寫在了Catch中。弱弱的說一句,這種情況干嘛不用ifelse呢。

而實際情況是,異常處理只是用戶處理軟件中出現異常的情況。常用的情況是子程序拋出錯誤,讓上層調用者知道,子程序發生了錯誤,并讓調用者使用合適的策略來處理異常。一般情況下,對于異常的處理策略就是Crash,讓程序死掉,并且打印出堆棧信息。

而在IOS編程中,拋出錯誤的方式,往往采用更直接的方式。如果上層需要知道錯誤信息,一半會傳入一個NSError的指針的指針:

- (void) doSomething:(NSError* __autoreleasing*)error { ... if(error != NULL) { *error = [NSError new]; } .... }

而能夠留給異常處理的場景就極少了,所以在IOS編程中盡量不要使用Try-Catch。
(PS:見到過使用Try-Catch來防止程序Crash的設計,如果不是迫不得已,盡量不要使用這種策略)
盡量將沒有Crash掉的BUG,讓它Crash掉
上面主要講的是怎么知道Crash的“BUG”。對于合理的制造“BUG”還有一條就是盡量把沒有Crash掉的“BUG”,讓他Crash掉。這個沒有比較靠譜的方法,靠暴力吧。比如寫一些數組越界在里面之類的。比如那些難調的多線程BUG,想辦法讓他Crash掉吧,crash掉查找起來就比較方便了。
總之,就是抱著讓程序“死掉”的心態去編程,向死而生。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 斷言(assert) 是指在開發過程是使用的,讓程序在運行時進行自檢的代碼 (通常是一個子程序或宏). 斷言為真,...
    MichalWilson閱讀 3,289評論 0 0
  • 1.老大要測試30個接口,判斷這些接口返回的數據對不對2.保證app在運行的過程中,實時監聽數據傳遞的正確性。2....
    mkb2閱讀 442評論 0 1
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,288評論 25 708
  • 夏至未至的時節,從Suki老師《穿衣有道,品型識人》的小班課走出來,看著天色尚早,天氣尚好,身后是意猶未盡的姑娘們...
    卿瘋閱讀 834評論 18 15