iOS開發技巧《Effective Objective-C 2.0》 讀后總結


  感覺自己最近提升很慢了。然后去找了一些面試題看看。發現自己自大了。在實際開發中,讓我解決bug、編寫功能,我有自信可以完成。但是對項目更深層的思考,我卻沒有。為了能進到自己的目標BAT。也為了讓自己更進一步發展。目前是計划是先看《Effective Objective-C 2.0》、《Objective-C高級編程:iOS與OS X多線程和內存管理》2本書,並將AFN、YYCache、SDWebImage等開源源碼再認真看一遍,並寫下自己的讀后總結。

  《Effective Objective-C 2.0》總結出編寫高質量iOS與OX X代碼的52個技巧。看完后,覺得還是有很多之前沒有注意到的地方,認識到自己的不足之處。這里總結就不一一列舉所有的技巧,重點是介紹我覺得比較實用的點,有些比較理論的知識比如對象所占的內存總是分配在“堆空間”就不在這里介紹了,有興趣的同學,可以去看看全本書,值得推薦。

  

  1.在類的頭文件中盡量少引用其他頭文件,因為過多引入頭文件會增加編譯時間。在.h中最好使用向前聲明"@class"方式。這樣一方面可以降低類之間的耦合,另一方面可以防止2個類的互相引用。

  2.盡量使用字面量語法來創建字符串、數值、數組、字典。這種方式看起來更加簡明扼要,而且創建數組、字典時可以保證不會出現nil。

1 //字面量語法:
2 NSNumber *intNumber = @1;
3 NSNumber *floatNumber = @1.2f;
4 int x = 5;
5 float y = 2.32f;
6 NSArray *arr = @[@"one",@"two",@"three"];
7 //其他語法創建就是比如的alloc等。。

  3.多用類型常量(static const),少用#define預處理指令。不要用預處理指令定義常量。這樣定義出來的常量不含類型信息,編譯器只是會在編譯前據此執行查找與替換操作。即使有人重新定義了常量值,編譯器也不會產生警告信息,這將導致應用程序中的常量值不一樣。另外使用類型常量時也要注意命名,是否要加前綴之類的。

  4.使用枚舉來表示狀態機的狀態、傳遞給方法的選項以及狀態碼等值。與創建結構體相比,創建對象還需要額外開銷,例如分配及釋放堆內存等。在處理枚舉類型的switch語句中不要實現default分支。這樣的話,加入新枚舉之后,編譯器就會指示開發者:switch語句並處理所有枚舉。

  5.iOS開發中幾乎所有屬性都聲明為nonatomic,這是因為iOS中使用同步鎖開銷很大,這會帶來性能問題,但是這不能保證“線程安全”,所以在特定的時候要學會修改為atomic,但是大部分時候還是用nonatomic。

  6.在對象內部盡量直接訪問實例變量。最直白的區別是在對象內使用:self.name是屬性訪問。_name是直接訪問。推薦_name。   

    兩種寫法的區別
    *由於不經過OC的方法派發步驟,所以直接訪問實例變量的速度比較快。
    *直接訪問實例變量時,不會調用其“設置”方法,這就繞過了為相關屬性所定義的“內存管理語義”。比方說,如果在ARC下直接訪問一個聲明為copy的屬性,那么並不會拷貝該屬性,只會保留新值並釋放舊值。
    *如果直接訪問實例變量,那么不會觸發“鍵值觀測KVO”通知。這樣做是否會產生問題,還取決於具體的對象行為。
    *通過屬性來訪問有助於排查與之相關的錯誤,因為可以給“獲取方法”、“設置方法”中新增“斷點”,監控該屬性的調用者及訪問時機。
    **在寫入實例變量時,通過其“設置方法”來做,而在讀取實例變量時,則直接訪問之。
  7.判斷對象是否相同時,除了要重寫isEqual方法之外還要重寫hash方法,保證hash密碼也要相同。
  8.判斷類對象時,“isMemberOfClass”能夠判斷出對象是否為某個特定類的實例。而“isKindOfClass”能夠判斷出對象是否為某類或其派生類的實例。這里盡量使用“isKindOfClass”,因為某些類可能實現了消息轉發功能。
  9.編寫自己的類庫時,最好加上自己的前綴。公司的項目則看項目組要求。
  10.實現description方法,可以更方便的打印出對象的信息。
  11.盡量使用不可變對象。
  12.使用清晰而協調的命名方式,方法名要言簡意賅,從左到右讀起來要像個日常用語中的句子。
  13.給私有方法的名稱加上前綴,這樣可以很容易 的將其公共方法區分開。
  14.OC的錯誤應該由NSError對象來輸出,如果不是重大錯誤,會導致程序崩潰的不要使用拋出異常。這和其他語言有很多的不同,因為在拋出異常的時候有可能會導致內存泄露,所以不支持過多使用,只有在重大錯誤才用。
  15.通過委托與數據源協議進行對象間通信。使用委托協議更有利於代碼的解耦。
  16.使用分類機制把類的實現划分成易於管理的小塊。
  17.勿在分類中聲明屬性。
  18.在dealloc方法里,應該做的事情是釋放指向其他對象的引用,並取消原來訂閱的“鍵值KVO”或NSNotificationCenter等通知。不要做其他事情。
  19.以弱引用避免保留環,即避免循環引用。
  20.以“自動釋放池塊”降低內存峰值。在for循環中使用更多,一遍創建信息,使用后釋放。即在for循環中一遍創建結束后就可以釋放,這樣內存峰值就不會太高。
  21.如果塊(block)所捕獲的對象直接或間接的保留了塊本身,那么就得當心保留環問題,不是每一個self都會循環引用,但是在使用時還需要多加注意。
  22.多用派發隊列(GCD),少用同步鎖。將同步和異步派發結合起來,可用實現與普通加鎖機制一樣的同步行為,而這么做卻不會阻塞執行異步派發的線程。使用同步隊列及柵欄塊,可以令同步行為更加高效。
  23.GCD更適合大體的多線程操作,如果要更細致的操作多線程則使用NSOperationQueue操作隊列,如需要取消線程操作、指定操作的優先級、監聽鍵值變化、指定操作間的依賴關系等。
  24.通過Dispatch Group機制,根據系統資源狀況來執行任務。
  25.使用dispatch_once來執行只需運行一次的線程安全代碼。(編寫單例對象時,推薦使用)。
  26.遍歷時多用塊枚舉,少用for循環。在數組中可能不明顯,但是在字典、set這些無序的信息時,使用for循環就需要性能額外的開銷了。而快速遍歷又不能有更全的對象信息,所以最推薦塊枚舉遍歷。
  27.緩存信息時,盡量使用NSCache,而非選擇NSDictionary。因為系統發出“低內存”的時候會自動刪減緩存,而不需要自己手動去刪減。而且NSCache是線程安全的,NSDictionary是絕對不具備此優勢的。還能可以給NSCache對象設置上限。如果緩存使用得當,那么應用程序的相應速度就能提高。只有那種“重新計算起來很費事的”數據,才值得放入緩存,比如那些需要從網絡獲取或從磁盤讀取的數據。
  28.在使用initialize與load這2個初始方法的時候要盡可能精簡。在里面設置一些狀態,使本類能夠正常運行就可以了,不要執行那種耗時太久或需要加鎖的任務。
  29.使用NSTimer主要循環引用和用完釋放的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM