读 Objective-C 高级编程(一)

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

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

书籍封面

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

自动引用计数

什么是自动引用计数

定义:自动引用计数是指内存管理中对引用采取的自动计数的技术。
注意点:在 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。这就是大致的实现过程啦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容