建議1 盡量使用系統(tǒng)控件
系統(tǒng)控件可以使得用戶容易上手,但在iPhone開發(fā)中還有很多人習(xí)慣使用checkbox而不是UISwitch,使用combobox而不是使用UIPickerView。究其原因可能有兩點:一是從其他Windows或者Android系統(tǒng)轉(zhuǎn)到iPhone開發(fā)的殘留,二是因為跨平臺開發(fā)中為了減少設(shè)計和資源的工作而趨同設(shè)計。不過這樣的設(shè)計往往造成自定義控件的開發(fā)投入,質(zhì)量上也往往無法和系統(tǒng)控件相媲美。
建議2 合理抽象
UI代碼是很容易重復(fù)寫的代碼,很多時候就會造成代碼效率的錯局,讓人有一種高效工作的錯覺。其實很多代碼是完全重復(fù)或者結(jié)構(gòu)重復(fù)的,通過適當?shù)某橄缶涂梢赃M行消除和避免。比如在一個應(yīng)用中,不同地方所需要的內(nèi)嵌網(wǎng)頁瀏覽器,這些地方往往都有一些共通的行為。比如加載的時候會顯示加載進度并在狀態(tài)欄顯示網(wǎng)絡(luò)狀態(tài)圖標,在加載完畢后隱藏進度和網(wǎng)絡(luò)狀態(tài)顯示。如果單獨在不同Controller中實現(xiàn)不僅不合理,而且容易造成大量代碼重復(fù)以至于后來的維護噩夢。通過合理抽象,抽取一個基類后就可以封裝這塊的行為,實現(xiàn)相同邏輯代碼的復(fù)用。
建議3 優(yōu)先使用組合。
UI中很多部分應(yīng)該像積木,可以隨意拼接組合。比如下圖的用戶信息顯示部分可以由諸如UIImageView,UILabel等幾個基本控件拼接而成,而這種顯示在一個項目中會通常在多個界面中顯示。面對這種的問題,參考建議2后可能就會想著抽象一個基類用來處理用戶信息顯示相關(guān)的邏輯和界面。所有有這需求的界面都可以繼承自這個基類。這種抽象是解決了邏輯和界面重復(fù)實現(xiàn)的問題,但另一方面卻引入了高耦合的繼承。如果有些界面因為功能原因更會迫切繼承一個其他基類,比如建議2中提到的處理網(wǎng)頁加載的基類,由于Objective-C無法支持多重繼承,從而被迫進行部分代碼的copy&paste。所以在抽象的時候就應(yīng)該格外珍惜基類的抽象的使用,不斷利用Liskov原則進行繼承合理性的檢查和確認,同時把握“優(yōu)先使用組合”的原則,通過基本控件的組合制作一些應(yīng)用相關(guān)的組合,比如顯示用戶信息的,這樣其他需要的節(jié)目就可以利用組合來復(fù)用這部分代碼,從而避免繼承,也其他更合理的繼承保留可能。
建議4 UI和邏輯的分開
這是很重要的一點,iPhone SDK給開發(fā)者提供了一個很好的基礎(chǔ)來實現(xiàn)UI和邏輯的分開,所以實現(xiàn)的過程中務(wù)必遵照一些Apple的指導(dǎo)文檔,而避免在UI中揉合著大量邏輯代碼。要真這樣的話不僅對不起Apple工程師在這方面的努力,更是給自己增加無盡的麻煩。
建議5 充分利用IB。
曾經(jīng)遇到這樣的一個同事,九幾年開始做MFC開始,最初也很希望使用STL庫,不過在一次項目中發(fā)現(xiàn)了STL的內(nèi)存泄露問題后就開發(fā)摒棄STL,以至到現(xiàn)在也不允許自己和屬下在項目開發(fā)中使用STL。這真是一朝被蛇咬,十年怕井繩。在使用Xcode進行iPhone開發(fā)的過程中同樣有這樣的一些人。他們很早就開始接觸和使用IB,但使用過程中發(fā)現(xiàn)很多IB的問題和不便,甚至有一些在實際項目中無法忍受,以至于到現(xiàn)在還一直抵觸IB。目前,雖不敢說IB已經(jīng)很完美,但是它對開發(fā)效率的提高所起的作用是毋庸置疑的。
建議6 不要低估了Apple工程師
在開發(fā)的過程中經(jīng)常會發(fā)現(xiàn)一些比較奇怪的問題,這時候通常就懷疑是不是Apple的bug,于是乎就開始尋找一些特殊處理進行規(guī)避并逐漸認定這就是Apple的問題。一旦有過這樣的經(jīng)歷后,以后遇到類似的問題就會首選自己發(fā)現(xiàn)的那些特殊處理,而逐漸偏離了開發(fā)的正道。舉個自己親身經(jīng)歷的例子,一次為了改變UITableViewCell的顏色,開始時直接改變cell的backgroundColor,但發(fā)現(xiàn)搞不定,一番搜索后發(fā)現(xiàn)改變cell的ContenView的backgroundColor就OK了,不過一旦顯示accessoryView就露餡了。于是乎干的徹底點,直接自定義一個UITableViewCell,并用一個UIImageView做背景,現(xiàn)在終于可以“為所欲為”了。不過回想下,怎么簡單的一個問題如此大動干戈,真是不值當,所以心里會暗暗罵下Apple的工程師,怎么就不讓cell的backgroundColor起作用呢?這么明顯的bug!以至于以后的一段時間我就習(xí)慣用那“土辦法”,而且是屢試不爽。突然有天在stackoverflow上看到一個類似問題的討論,原來這種問題可以通過重寫-tableView:willDisplayCell:forRowAtIndexPath:的委托方法實現(xiàn)。想想之前罵過的話以及走過的彎路,只能感嘆自己掌握不深入。有了這樣的經(jīng)歷后在遇到類似的問題我會先懷疑使用合理,而不是輕易下結(jié)論。