Effective Objective - C 2.0 筆記

Objective-C 入門

  1. Object-C 是 C 的超集,它使用運行時來進行動態綁定,所有對象的類型都是在運行時才能確定的,都是以消息傳遞的機制運作;所有對象都是在heap中allocated的,在stack中allocate對象是不合法的;內存管理在objc中被抽象為以引用計數的方式來進行管理。

  2. 最小化在頭文件中import的頭文件數量,在盡可能的深處引用它;使用提前聲明,消除多余的引用,消除互相引用;使用 continuation category 細化類別 來減少 多余的類方法造成的 過多編譯量。

  • 對于NSArray、NSNumber、NSDictionary的快捷初始化方法,使用literals語法,使代碼更加簡潔,更加安全,但只能創建immutable的對象,對于mutable的對象需要使用mutableCopy

     NSMutableArray *mutable = [@[@1,@2,@3,@4,@5] mutableCopy]; 
    
  1. 選擇使用

    static const NSIntger durantion = 1;  
    

    來代替

    #define durantion 1 
    

    定義常量,優點在于避免重定義造成的錯誤、加入global symbol Table能多處使用、更加嚴格的類型定義

對象,消息與運行機制

  1. 最好用直接訪問的方法來讀取成員變量,而用property生成的setter方法來賦值成員變量;
    直接賦值更加快速,但會失去了對成員變量制定的property屬性的內存控制;并且不會觸發對于該成員變量 KVO 監聽函數;
    初始化函數中,最好對成員變量直接賦值,因為可能在子類中重載的setter方法會做出特殊的過濾處理;當然,如果該成 員變量只聲明在此類的父類中,那只能調用setter方法;
    如果成員變量是使用lazy initialization 方法,如

     - (IFObject*)object  
     {  
         if(!_object)  
         {  
             _object = [IFObject new];  
         }  
         return _object;     
     }  
    

    那讀取它時需要調用它的getter方法,否則會出錯。

  2. 使用動態綁定對象,使代碼更優雅

    void (^block)(NSInteger) = objc_getAssociatedObject(alertView, kAlertKey);  
    

    用Key獲取與該對象關聯的對象或block
    可以視為Key/Value方式的擴展,需要 #import <objc/runtime.h>
    在AlertView中,我們可以在聲明每個AlertView后將處理其點擊的delegate方法寫為block,與該alertView綁定,這樣能 夠避免同個類文件聲明多個AlertView后委托方法的臃腫不堪
    同理,可應用在多個場景中。

  3. 了解Objective-C的msgSend機制及函數混淆機制;

  4. 使用[object isKindOfClass:]檢查是否為該類或其子類,使用[object isMemberOfClass:]檢查是否為該類;

對象接口設計

  1. 在命名類時,多使用三字母前綴(避免與系統二字母前綴沖突)避免命名空間沖突;
    引入第三方庫時,修改庫命名,加入自定義的前綴,以防多次引入第三方庫導致的命名空間沖突。
  2. 一個類必須只有一個指定的初始化方法,其他初始化方法都最終指向它;
    在子類中只需要重載指定初始化方法即可;
  3. 定義類的description方法,返回描述對象的NSString,使對象能被NSLog輸出;
    若需要,定義類的dubugDescription方法,提供更加詳細的描述方法;
  4. 偏向immutable對象,防止mutable對象在運行時的修改導致程序異常;
    盡可能類頭文件只暴露具有readonly屬性的property,若在類內部需要修改該成員變量,可使用直接訪問,或在class-continuation catalogy里將該property的屬性定義為readwrite;
    提供一個修改類成員變量的公共方法,而不是將一個可變的成員變量暴露在頭文件中;
  5. 在類接口命名上按照Objc的標準進行命名,在命名上表意清晰并完整,向句子一樣表述接口作用;
  6. 在Objc中,沒有一個能將類中成員或方法定義為private的方法,偏向用p_前綴修飾private變量與方法,以便于公共方法區分開來;
  7. 若是程序發生致命錯誤,用NSException來拋出異常終止程序,在非致命錯誤上,返回nil或者0,或者返回一個NSError對象通過委托方法等方式對錯誤進行處理;

委托與協議

  1. 使用delegate委托模型進行對象間的消息傳遞,優化點為可以使用緩存機制來保存委托對象的消息響應狀況(之后再寫文章詳細描述);

  2. 使用categories擴展類別技術分割類文件,實現類方法功能的分類,防止單一類文件代碼過于冗長;也可以創建一個private的類別,表示類的私有方法;

  3. 當自定義或引入categories時,盡可能加上自定義的前綴,以免與系統類別定義沖突;

  4. 無法在categories類別(除continuation categories)添加property,在添加的類別中,property成員變量是無法進行synthesized,因此無法為property提供gettersetter方法;解決方法只有自定義property的訪問與修改方法,并加上

    @dynamic property
    

    來表明property的的訪問與修改方法在運行時生成;

  5. 在類的實現文件中使用class-continuation categories技術

    @interface WYObject()
    //Property and method
    @end
    

    這個類別可用于

    • 可以添加成員變量方法到類中,因此可以隱藏無需公開在頭文件的成員變量;
    • 可以重新聲明頭文件中聲明的property,修改其屬性,如將readonly改為readwrite
    • 聲明類的私有函數(可以不在類別中聲明,但這能增加可讀性);
    • 能夠在類別中聲明類遵守的protocols協議,若該類不希望公開;
  6. 使用protocol協議來提供一個匿名類

    @property (nonatomic,weak) id<WYDelegate> delegate
    

    當一個對象的類型需要被隱藏,或者對象實現了什么方法比對象類型更重要時,可以采用匿名類。

內存管理

盡管現在已經是ARC的年代了,但是ARC的本質是系統在程序的適當地方添加上內存管理代碼,因此對于內存管理的技術還是需要了解清楚地。

  1. 程序中,所有對象通過引用關系組成一張內存計數的對象圖,在一個對象的聲明周期中,對其的retain與release次數必須相等;
  2. 使用@autureleasepool內存池,加在大量動態內存生成的代碼中,使內存池立即釋放內存,防止內存高峰導致程序crash;
  3. 禁止使用retainCount方法,因為在程序的某一刻,retainCount返回的數值是不能確定的。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容