Chapter 3. Interface and API Design
<br />
Item 19: Use Clear and Consistent Naming
<br />
這一節(jié)講的是編程三大難題之一:變量與函數(shù)的命名。
其實(shí)并沒(méi)有講變量的命名...大概是因?yàn)樽兞慷际敲~偿枕,只有我們這種非母語(yǔ)的人才會(huì)糾結(jié)吧_(:з」∠)_ 這一節(jié)內(nèi)容在文檔Coding Guidelines for Cocoa。
OC的方法格式看習(xí)慣了還挺喜歡的。非常有人文關(guān)懷悔捶。長(zhǎng)是長(zhǎng)了恃逻,一看就明白晶府,第一次見(jiàn)也不用查方法是要做什么,各個(gè)參數(shù)代表什么抢埋,這就是我們常說(shuō)的犧牲空間換時(shí)間(誤)。文中實(shí)力嘲諷了C++和java的方法命名督暂,對(duì)比展示OC命名優(yōu)越性揪垄。
具體說(shuō)來(lái)有以下幾個(gè)注意:
- 不使用簡(jiǎn)稱(chēng)。
- 不要濫用“get”逻翁。然而這一點(diǎn)文中的敘述我并不是特別明白…
- 關(guān)于長(zhǎng)句子的方法名饥努,有返回值的,返回值所表示的名詞放在最前面八回,后面每個(gè)參數(shù)酷愧,類(lèi)型聲明之前都應(yīng)該是這個(gè)參數(shù)代表的名詞。不需要寫(xiě)and缠诅。動(dòng)詞和介詞放在中間溶浴。
- init和工廠方法仿照官方來(lái)寫(xiě),基本上是加with管引。
- 代理方法盡量以本類(lèi)作為開(kāi)頭士败。
- 類(lèi)和代理名都要加前綴,代理名就用類(lèi)名+delegate褥伴。
說(shuō)起來(lái)谅将,命名這種事情,和語(yǔ)言一樣重慢,還是得文檔看得多了才能比較有感覺(jué)吧戏自。
<br />
Item 20: Prefix Private Method Names
<br />
這一節(jié)很短,說(shuō)的是為private method加前綴伤锚。
表示驚嚇( ⊙ o ⊙ )擅笔。我從來(lái)沒(méi)給private method加過(guò)前綴…
好處有二:
- 一是在調(diào)試中可以清楚地看清哪些方法是private志衣,哪些方法是public。
- 二是知道了是private就明白不會(huì)影響外界API猛们,方便改動(dòng)念脯。而其余的public method改動(dòng)起來(lái)就要更三思。
我覺(jué)得這兩條其實(shí)說(shuō)的是一回事弯淘。
具體添加什么前綴呢绿店。并不是類(lèi)名那種三個(gè)字母的前綴。文中推薦的是子母+下劃線的形式庐橙,比如’p_’假勿。不要只用一個(gè)下劃線,以免和官方的方法名相沖突态鳖。
<br />
Item 21: Understand the Objective-C Error Model
<br />
這一節(jié)主要講NSError的使用转培。
開(kāi)頭先說(shuō)了NSException。NSException是遇到fatal error時(shí)才會(huì)使用的浆竭,拋出異常以后程序也應(yīng)該直接終止浸须,這樣就不用再關(guān)心因?yàn)閽伋霎惓6鵁o(wú)法執(zhí)行后面釋放資源的代碼,使得內(nèi)存泄露的問(wèn)題了邦泄。但如果是比較小的錯(cuò)誤删窒,并不希望程序因此退出,所以如果能用NSError處理就不要使用它顺囊。
NSError的詳細(xì)使用參照Error Handling Programming Guide肌索。
常用到的三個(gè)屬性是code,domain和userInfo特碳,因?yàn)槌跏蓟椒ㄐ枰_定的就是這三個(gè)參數(shù)驶社。三個(gè)屬性都是readonly的。
domain -> code -> user info 按順序?qū)﹀e(cuò)誤提供越來(lái)越詳細(xì)的描述测萎。domain可以看到是哪個(gè)系統(tǒng)出錯(cuò)亡电,code可以看到錯(cuò)誤的具體名字,一般采用enum來(lái)定義硅瞧,看到code已經(jīng)可以明白是什么錯(cuò)了份乒,或者已經(jīng)可以復(fù)制到搜索欄了...user info是一個(gè)字典,里面的信息更加詳細(xì)腕唧。
文中列舉了兩個(gè)常見(jiàn)的使用場(chǎng)景或辖。
一種是作為待處理的傳入?yún)?shù),像這樣:
- (void)connection:(NSURLConnection *)connection didFailWithError: (NSError *)error
這種在網(wǎng)絡(luò)傳輸相關(guān)的函數(shù)和block里都很常見(jiàn)枣接。
第二種我還沒(méi)見(jiàn)過(guò)颂暇,是作為輸出參數(shù)回調(diào),像這樣:
- (BOOL)doSomethig:(NSError **)error
回調(diào)以后的用法:
NSError *error = nil;
BOOL ret = [object doSomething: &error];
if (error){
\\
}
也就是說(shuō)但惶,方法調(diào)用的時(shí)候傳遞的是error的指針耳鸯,調(diào)用完成后通過(guò)這個(gè)指針就直接能得到error對(duì)象和里面的信息了湿蛔,雖然是作為參數(shù)傳進(jìn)去的,作用卻類(lèi)似于返回值县爬。并且阳啥,在方法執(zhí)行完畢后,系統(tǒng)會(huì)保證這個(gè)error對(duì)象可以自動(dòng)釋放财喳。
<br />
Item 22: Understand the NSCopying Protocol
<br />
這一節(jié)講應(yīng)該怎樣為自定義類(lèi)實(shí)現(xiàn)NSCopying協(xié)議察迟。
NSCopying協(xié)議是針對(duì)可以允許copy操作的類(lèi)。實(shí)現(xiàn)這個(gè)協(xié)議耳高,如果是普通的類(lèi)扎瓶,只需要實(shí)現(xiàn)一個(gè)方法:
- (id)copyWithZone: (NSZone *)zone
而如果是有immutable和mutable兩個(gè)版本的類(lèi),則需要實(shí)現(xiàn)兩個(gè)方法:
- (id)copyWithZone:(NSZone *)zone
- (id)mutableCopyWithZone:(NSZone *)zone
也就是說(shuō)泌枪,當(dāng)我們調(diào)用[someObject copy];
或[someObject mutableCopy]
時(shí)概荷,背后調(diào)用的就是這兩個(gè)方法。這里的zone參數(shù)編程的時(shí)候都不用去管它工闺,交給系統(tǒng)自動(dòng)完成。
默認(rèn)習(xí)慣是瓣蛀,copy返回的是immutable對(duì)象陆蟆,mutableCopy返回的是mutable對(duì)象,不管原對(duì)象可變與否惋增,copy出來(lái)的新對(duì)象都是這個(gè)規(guī)律叠殷。
就方法的具體寫(xiě)法來(lái)說(shuō),就是創(chuàng)建一個(gè)新的對(duì)象诈皿,把需要copy的值賦值給這個(gè)新的對(duì)象林束,然后返回即可。文中有一個(gè)EOCPerson的例子稽亏,很清晰壶冒。
系統(tǒng)的所有collection默認(rèn)情況下執(zhí)行的是shallow copy,所以一般我們也是這么做截歉。如果非常想做deepCopy胖腾,也可以專(zhuān)門(mén)再寫(xiě)一個(gè)deepCopy方法,比如系統(tǒng)的NSSet就有專(zhuān)門(mén)的深拷貝init方法瘪松,在寫(xiě)deepCopy時(shí)可以對(duì)所需copy的屬性調(diào)用這個(gè)方法咸作,就可以實(shí)現(xiàn)整個(gè)類(lèi)的deep copy了。