讀 Objective-C 高級編程(一)

前一段時間和一同事聊天,聊到一個話題,關于學習曲線的的話題,雖說有很多不一致,但有一點我們一致認同的深度決定高度!為此,我再次看了這本書(Objective-C 高級編程)。

該書從以下三部分出發,自動引用計數、Blocks、Grand Central Dispatch,在源代碼的基礎上加以解說,深入剖析。 非常建議購買看原版書籍!非常值得???/strong>,因為第一遍可能看不懂,哈哈哈。

書籍封面

在此,我以筆記的形式,邊學習,邊記錄,便于自己堅持。

自動引用計數

什么是自動引用計數

定義:自動引用計數是指內存管理中對引用采取的自動計數的技術。
注意點:在 LLVM 編譯器中設置 ARC 為有效狀態,就無需再次輸入 retain 或者是 release 代碼。
好處:這在降低程序奔潰,內存泄露等風險的同時,很大程度上減少了開發程序的工作量。

內存管理 / 引用計數

2.1 引用計數的機制理解
以經典的開燈例子舉例,在辦公室內至少有一人保持開燈狀態,無人時保持關燈狀態

最早進入辦公室的人   ===> 開燈      ==== > 生成對象 
之后進入辦公室的人   ===> 需要照明   ==== > 持有對象 
下班離開辦公室的人   ===> 不需要照明  ==== > 釋放對象
最后下班離開辦公室的人===> 關燈       ==== >  廢棄對象

中間無論多少人,只要遵循進來就需要照明,走就不要照明。這樣辦公室的照明就可以得到很好的管理;同理使用引用計數功能,對象也能夠得到很好的管理。

注意:release方法當引用計數等于零時會自動使用dealloc方法。
原則:

  • 自己生成的對象,自己持有。
  • 非自己生成的對象,自己也能持有。
  • 不再需要自己持有的對象時釋放。
  • 非自己持有的對象無法釋放。

** 2.2、alloc,retain,release的實現的理解 **

由于 NSObject 的源碼沒有公開,此利用 Xcode 的調試器和 iOS 大概追溯其實現過程。

  • alloc
alloc 的實現
+alloc
+allocWithZone:
Class_createInstance
calloc

alloc類方法首先調用 allocWithZone:類方法,然后調用 class_instance 函數,最后通過 calloc 來分配內存塊。這樣就相當于 alloc 的實現啦。

  • retain、release
模擬 retain\release實現方法
int __CFDoExternRefOpreation(uintptr_t op, id obj) {
    CFBasicHashRef table = 獲取對應的是散列表obj(); // 獲取對應的是散列表
    int count;
    switch (op) {
        case OPREATION_retainCount:
            count = CFBasicHashGetCountOfKey(table, obj);
            return count;
        case OPREATION_retain:
            count = CFBasicHashAddVlaue(table, obj);
            return count;
        case OPREATION_release:
            count = CFBasicHashRemoveValue(table, obj);
            // count == 0的時候,調用 dealloc
            return 0 == count;
    }
}

然后真正的對象實現的方法也許如下:

- (NSUInteger)reatainCount
{
    return (NSUInteger) __CFDoExternRefOpreation(OPREATION_retainCount, self);
}

- (id)retain
{
    return (id) __CFDoExternRefOpreation(OPREATION_retain, self);
}

- (void)release
{
    return  __CFDoExternRefOpreation(OPREATION_release, self);
}

蘋果的實現大概是采用 散列表(引用計數表)來管理引用計數器。
這樣做的好處:

對象用內存筷發分配無需考慮內存塊的頭部。
引用計數表各記錄都有內存塊地址,可從各個記錄追訴哦到各對象的的內存塊。
同時檢測內存泄露時,很方便檢測各對象的持有者是否存在

以上大致是 retain 、release 的理解,NSObject 在實例化該方法的時候先去調用一個類似 CFDoExternRefOpreation的函數,然后實現相應的方法 CFBasicHashRemoveValue 或 CFBasicHashAddVlaue,通過CFBasicHashRef table (引用計數表)整體的管理它的引用計數,來實現 retain 或 release。這就是大致的實現過程啦。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容