“好記性不如爛筆頭”,雖然我不是用的筆卵牍,但是敲一遍效果對我來說肯定更好!B倜凇糊昙!
? ? 首先要注意的是“自動引用計數(shù)”在默認情況下不是“異常安全的”。具體來說谢谦,這意味著:如果拋出異常释牺,那么本應(yīng)該在作用域末尾釋放的對象現(xiàn)在卻不會自動釋放了。即使不使用ARC回挽,也很難寫出在拋出異常時不會導(dǎo)致內(nèi)存泄露的代碼没咙。
? ? Object-C現(xiàn)在所采用的辦法是:只在極其罕見的情況下拋出異常,異常拋出之后無須考慮恢復(fù)問題千劈,而且應(yīng)用程序在此時也應(yīng)該退出祭刚。這就是說不用再編寫復(fù)雜的“異常安全”代碼了。
? ? 比如說你寫了一個抽象基類墙牌,它的正確用法是先從中繼承一個子類涡驮,然后再使用這個子類。在這種情況下喜滨,如果有人直接使用了這個抽象基類捉捅,那么可以拋出異常。與其他語言不同虽风,OC中沒有辦法將某個類標示為“抽象類”棒口。要想達成類似效果,最好的辦法就是在那些子類必須覆寫的父類方法里面拋出異常辜膝。
? ? 異常只用于處理嚴重的錯誤(fatal error,致命錯誤)无牵,在其他不嚴重的或者說不致命的錯誤中,OC所采取的編程范式為:令方法返回nil/0内舟,或者是使用NSError合敦,以表明有錯誤發(fā)生。比如根據(jù)傳入的參數(shù)無法初始化當前實例验游,那么就返回nil/0:
? ? 在這種情況下充岛,如果if語句發(fā)現(xiàn)無法用傳入的參數(shù)值來初始化當前實例保檐,那么就把self設(shè)置為nil,這樣的話整個方法的返回值也就是nil了崔梗。
NSError的用法更加靈活夜只,因為經(jīng)由此對象,我們可以把導(dǎo)致錯誤的原因回報給調(diào)用者蒜魄。
NSError對象里封裝了三條信息:
Error domain(錯誤范圍扔亥,其類型為字符串):錯誤發(fā)生的范圍。也就是產(chǎn)生錯誤的根源谈为,通常用一個特定的全局變量來定義旅挤。比方說:“處理URL的子系統(tǒng)”在從URL中解析或取得數(shù)據(jù)時如果出錯了,那么就會使用NSURLErrorDomain來表示錯誤范圍伞鲫。
Error code(錯誤碼粘茄,其類型為整數(shù)):獨有的錯誤代碼,用以指明某個范圍內(nèi)具體發(fā)生了何種錯誤秕脓。某個特定范圍內(nèi)可能會發(fā)生一系列相關(guān)錯誤柒瓣,這些錯誤情況通常采用enum來定義。例如吠架,當HTTP請求出錯時芙贫,可能會把HTTP狀態(tài)碼設(shè)置為錯誤碼!
User info(用戶信息傍药,其類型為字典):有關(guān)此錯誤的額外信息磺平,其中或許包含一段“本地化的描述”或許還含有導(dǎo)致該錯誤發(fā)生的另外一個錯誤,經(jīng)由此種信息怔檩,可將相關(guān)錯誤串成一條“錯誤鏈”褪秀。
? ? 在設(shè)計API時,NSError的第一種常見用法是通過委托協(xié)議在傳遞此錯誤薛训。有錯誤發(fā)生時媒吗,當前對象會把錯誤信息經(jīng)由協(xié)議中的某個方法傳給其委托對象(delegate)。例如:NSURLConnection在其委托協(xié)議NSURLConnectionDelegate之中就定義了如下方法:? ??
? ? 當NSURLConnection出錯之后(比如超時了)乙埃,就會調(diào)用此方法以處理相關(guān)錯誤闸英。這個方法不是調(diào)用者必須實現(xiàn)的,但是比拋出異常要好介袜,因為調(diào)用者至少可以自己決定是否需要NSURLConnection回報此錯誤甫何。
? ? NSError的另外一種常見用法是:經(jīng)由方法的“輸出參數(shù)”返回給調(diào)用者。比如:
? ? 像這樣的方法一般都會返回BOOL值遇伞,用以表示該操作是成功了還是失敗了辙喂。如果調(diào)用者不關(guān)心具體的錯誤信息,直接判斷布爾值就行了。否則就檢查經(jīng)由“輸出參數(shù)”所返回的那個錯誤對象巍耗。
? ? 實際上秋麸,在使用ARC的時候,編譯器會把方法簽名中的NSError**轉(zhuǎn)換成NSError * __autoreleasing*炬太,也就是說指針所指向的對象會在方法執(zhí)行完畢后自動釋放灸蟆。這個對象必須自動釋放,因為"doSomething:"方法不能保證其調(diào)用者可以把此方法中創(chuàng)建的NSError釋放掉亲族,所以必須加入autorelease炒考。
? ? NSError對象里面的domain、code霎迫、user information應(yīng)該按照具體的錯誤情況填入適當?shù)膬?nèi)容斋枢。這樣的話調(diào)用者就可以根據(jù)錯誤類型分別處理各種錯誤了。錯誤范圍應(yīng)該定義成NSString類型的全局常量女气,錯誤碼則定義成枚舉類型更好杏慰。例如: