读 Objective-C 高级编程(一)

前一段时间和一同事聊天,聊到一个话题,关于学习曲线的的话题,虽说有很多不一致,但有一点我们一致认同的深度决定高度!为此,我再次看了这本书(Objective-C 高级编程)。

该书从以下三部分出发,自动引用计数、Blocks、Grand Central Dispatch,在源代码的基础上加以解说,深入剖析。 非常建议购买看原版书籍!非常值得常看,因为第一遍可能看不懂,哈哈哈。

书籍封面

在此,我以笔记的形式,边学习,边记录,便于自己坚持。

自动引用计数

什么是自动引用计数

定义:自动引用计数是指内存管理中对引用采取的自动计数的技术。
注意点:在 LLVM 编译器中设置 ARC 为有效状态,就无需再次输入 retain 或者是 release 代码。
好处:这在降低程序奔溃,内存泄露等风险的同时,很大程度上减少了开发程序的工作量。

内存管理 / 引用计数

2.1 引用计数的机制理解
以经典的开灯例子举例,在办公室内至少有一人保持开灯状态,无人时保持关灯状态

最早进入办公室的人   ===> 开灯      ==== > 生成对象 
之后进入办公室的人   ===> 需要照明   ==== > 持有对象 
下班离开办公室的人   ===> 不需要照明  ==== > 释放对象
最后下班离开办公室的人===> 关灯       ==== >  废弃对象

中间无论多少人,只要遵循进来就需要照明,走就不要照明。这样办公室的照明就可以得到很好的管理;同理使用引用计数功能,对象也能够得到很好的管理。

读 Objective-C 高级编程(一)_第1张图片

注意:release方法当引用计数等于零时会自动使用dealloc方法
原则:

  • 自己生成的对象,自己持有。
  • 非自己生成的对象,自己也能持有。
  • 不再需要自己持有的对象时释放。
  • 非自己持有的对象无法释放。

** 2.2、alloc,retain,release的实现的理解 **

由于 NSObject 的源码没有公开,此利用 Xcode 的调试器和 iOS 大概追溯其实现过程。

  • alloc
读 Objective-C 高级编程(一)_第2张图片
alloc 的实现
+alloc
+allocWithZone:
Class_createInstance
calloc

alloc类方法首先调用 allocWithZone:类方法,然后调用 class_instance 函数,最后通过 calloc 来分配内存块。这样就相当于 alloc 的实现啦。

  • retain、release
读 Objective-C 高级编程(一)_第3张图片
模拟 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。这就是大致的实现过程啦。

你可能感兴趣的:(读 Objective-C 高级编程(一))