iOS-《編寫高質量程式碼》筆記-第一章

道明白發表於2017-12-05

《編寫高質量程式碼》 作者 劉一道

看這本書的過程中,做了一些筆記,分享一下。

建議1:視OC 為一門動態語言

寫程式碼的時候切忌心態浮躁,急功近利。

OC和C++ 都是在C的基礎上加入物件導向特性擴充而成的程式設計語言,OC是基於動態執行時型別,而C++基於靜態型別。

用OC 編寫的程式不能直接編譯成可令機器讀懂的機器語言(二進位制編碼),而是在程式執行時,通過執行時(Runtime)把程式編譯成可令機器讀懂的機器語言。

OC 作為一門動態開發語言,會盡可能地將編譯和連結時要做的事情推遲到執行時。這意味著OC語言不僅需要一個編譯環境,同時也需要一個執行時(Runtime)系統來執行編譯好的程式碼。

在一定程度上,執行時系統類似於OC 語言的作業系統,OC 就基於該系統來工作。因此,執行時系統好比OC 的靈魂,很多東西都是在這個基礎上出現的。

 靜態開發語言執行效率要比動態開發語言高,因為一部分CPU計算損耗在了執行時系統過程中。

OC 是動態語言,C++是靜態語言。

靜態語言執行效率和安全性要動態語言高,但其簡便性沒有動態語言高。

執行時(Runtime)環境可處理弱型別、函式存在檢查工作,會檢測註冊列表裡是否存在對應的函式,型別是否正確,最後確定正確的函式地址,再進行儲存暫存器狀態、壓棧、函式呼叫等實際操作,確保了OC 的靈活性。

參考連結:  http://www.cnblogs.com/ioshe/p/5489086.html#3846100

建議2:在標頭檔案中儘量減少其他標頭檔案的引用

#import 和 @class 在編譯效率方面存在著巨大的差異,假如,有100個標頭檔案,都用#import 引用了同一個標頭檔案,或者這些檔案是依次引用的,如A->B,B->C,C->D這樣的引用關係。當最開始的那個標頭檔案有變化時,後面所有引用它的類都需要重新編譯,如果自己的類有很多話,這將浪費大量的時間,而使用@class 則不會。

建議3:儘量使用const、enum來替換預處理#define

#define 定義了一個巨集,在編譯開始之前就會被替換。 

相對字串字面量或數字,更推薦使用常量,應使用static方式宣告常量,而非使用#define 的方式來定義巨集。

恰當用法:

 static NSString * const  EMCompanyName = @”RenRenSheJi”;

static const CGFloat  EMImageHeight = 50.0;

不當用法如下:

#define CompanyName  @”RenRenSheJi”

#define  imageHeight    2

對於整數型別,代替#define 比較好用的方法就是使用enum.

NS_OPTIONS :一般用來定義位移相關操作的列舉值。

NS_ENUM: 一般用來定義普通的列舉。

參考連結:http://blog.csdn.net/u014205965/article/details/45913747

                    http://www.jianshu.com/p/12db1a648b69

要點:

     1.  儘量避免使用#define 預處理命令。#define 預處理命令不包含任何的型別資訊,僅僅是在編譯前做替換操作。它們在重複定義時不會發出警告,容易在整個程式中產生不一致的值。

     2.在原始檔(.m)中定義的static const 型別常量因為無須全域性引用,所以它們的名字不需要包含名稱空間。

        名稱空間:http://blog.csdn.net/lf_2016/article/details/51930792

    3.在標頭檔案中定義的全域性引用的常量,需要關聯定義在原始檔(.m)中的部分。因為需要被全域性引用,所以它們的名字需要包含名稱空間,通常是用它們的類名作為命名字首。

    4.儘量用NS_ENUM 和 NS_OPTIONS 巨集來實現列舉。

建議4:優先使用物件字面量語法而非等效方法

物件對面量:Object Literals 

字面量建立的陣列是不可變陣列,轉化成可變陣列需要mutableCopy:

NSMutableArray *array = [ @[@”a”,@”b”]   mutableCopy];

建議5:處理隱藏的返回型別,優先選擇例項型別而非id

僅有在作為返回值時,宜用instancetype 來替換id,而不是代替程式碼中所有id。 與id 不同,instancetype 關鍵字僅能作為方法宣告的返回型別。

作為返回值,id 由於其自身的缺陷,在Objective-C中會逐漸退出,有instancetype 來替代。

使用instancetype 可避免隱式轉換id 而造成的欺騙性編譯無誤通過的現象,防止程式證書執行時出現崩潰現象,可以大大改善OC 程式碼的型別安全。

建議6:儘量使用模組方式與多類建立複合關係

引入預編譯標頭檔案(Pre-compiled Headers,PCH),即把公用的標頭檔案放入預編譯標頭檔案中預先進行編譯。通過在編譯的預處理階段,預先計算和快取需要的程式碼;然後在真正編譯工程時再將預先編譯好的產物加入到所有待編譯的原始檔中去,來加快編譯速度。利用預編譯標頭檔案雖然可以加快編譯的時間,但是這樣面臨的問題是,在工程中隨處可用本來不能訪問的東西,而編譯器也無法準確給出錯誤或者警告,無形中增加了出錯的可能性。

開啟使用模組:

     在專案的Build Settings 中通過搜尋Modules 找到這個選項,將Enable Moudules 選項設為YES.

     自己不需要把所有的#import都換成@import,因為編譯器會隱式地轉換它們,但是還是建議儘可能地用新語法來編寫程式碼。

要點:

 1.#include 和 #import ,其根本就是簡單的複製、貼上,將目標.h檔案中的內容一字不落地複製到當前檔案中,後者可以避免多次的重複引用。

2.以預編譯標頭檔案的方式,雖可縮短編譯時間,但其維護棘手,不利於廣泛應用。

3.模組功能,其應用不僅僅表現於編譯的速度加快,同時在連結框架等方面也非常好用。

4.啟動模組功能後,編譯器會隱式地把所有的#import 都轉化成 @import。

建議 7:明解Objective-C++ 中的有所為而有所不為

OC 編譯器允許使用者在同一個原始檔(.m)裡自由地混合使用C++ 和 OC ,混編後的語言叫作Objective-C++。

1.C++ 和 OC 在定義上結構上一樣,但是後者的繼承是封閉的。

2.OC 介面中定義的C++類是全域性範圍的,而不是OC 類的內嵌類。

3.C++ 和 OC 的物件模型不能直接相容。與OC不同的是,C++物件是靜態型別的,有執行時系統多型是特殊情況。

4.C++ 和 OC 有詞彙歧義和衝突。

5.C++ 和 OC 兩者功能上有限制。Objective C++沒有為OC 類增加C++ 的功能,也沒有為C++ 類增加Objective-C 的功能。 


相關文章