美文网首页Objective-C深入学习之旅
内存管理/引用计数(1)

内存管理/引用计数(1)

作者: 为爱而鬼 | 来源:发表于2019-02-27 17:11 被阅读0次

        本文学习方向与部分内容借鉴《Objective-C高级编程iOS与OS X多线程和内存管理》一书,个人认为深入了解OC是不能错过这本书的。一个狮子脑袋的封面很容易让人印象深刻,无论是否学习过这本书的苹果开发者,大部分都听过说这本书吧,此书很经典,有兴趣的朋友可以去学习学习。

        自动引用计数(ARC,Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术。在Objective-C中采用ARC机制,让编译器来进行内容管理。在Apple LLVM3.0之后编译器中设置ARC为有效状态(其实现在ARC已经是默认状态了),就无需再次键入retain或release代码,这在降低程序崩溃,内存泄漏等风险的同时,很大程度上减少了开发程序的工作量。编译器完全清楚目标对象,并能立刻释放那些不再被使用的对象。如此一来,应用程序将具有可预见性,其能流程运行,速度也将大幅提升。

        与自动引用计数相对的那就是手动引用计数(MRC, Manual Reference Counting),在苹果 WWDC 2011 提出ARC之前,开发者就是手动管理内存的,虽然距离现在确实很遥远了,但是学习一门语言的发展中的变化,对自己的深度提高有很大的作用的哦。

        书中用了开关房间灯的例子来说明引用计数的机制,例子的需求是办公室只要有人灯就应该亮着,一个人都没有灯才熄灭(不去考虑那些乱七八糟的情况)。解决这一问题的办法是使办公室在还有至少1人的情况下保持开灯状态,而在无人时保持关灯状态。1.最早进入办公室的人开灯,2.之后进入办公室的人,需要照明,3.下班离开办公室的人,不需要照明,4.最后离开办公室的人关灯(此时已无人需要照明)。这里用计数的方式来计算需要照明的人数,当办公室没有人的时候,需要照明的人数为0,每当有一个人来到办公室需要照明的人数就会加1,第一个人进入办公室需要照明的人数就变成了1,第二个人进入办公室需要照明的人数就变成了2,所以只要需要照明的人数大于1就应该开灯;每当有一个人离开办公室需要照明的人数就会减1,所以最后一个人离开的时候需要照明的人数就会变成0,因此就应该关灯。

        此类例子有很多,例如开车停车,只要车上有人就应该开车,车上没人就应该停车(还是开关灯这个例子比较经典,面试的时候被问到引用计数,用这个例子来解答应该很帅)。针对开关灯这个例子,对照明设备所做的动作相当于对Objectvie-C对象所做的动作,开灯相当于生成对象,需要照明相当于持有对象,不需要照明相当于释放对象,关灯相当于废弃对象。书中运用了很多图表来描述开关灯的情况,我就不一一描述了,用我个人的想法总结就是公共的东西都可以被使用,这就衍生到了内存管理的思考方式了。

        引用计算其实不应该把注意力放到计数上,更加客观,正确的思考方式是:自己生成的对象,自己所持有;非自己生成的对象,自己也可能持有;不再需要自己持有的对象释放;非自己持有的对象无法释放。这里其实可以这样理解你用公款给办公室买了一个电风扇,当然你自己可以使用电风扇,但是办公室其他的员工也是可以使用电风扇的,当你不想吹电风扇的时候就坐到一个电风扇吹不到的地方,当所有人都不用电风扇的时候,关掉电风扇,当然你是没有资格去旁边办公室关掉别人的电风扇的,并且那个电风扇和你是没有任何关系的。

        生成并持有对象(alloc/new/copy/mutableCopy等方法),持有对象(retain方法),释放对象(release方法),废弃对象(dealloc方法)。这些有关objective-C内存管理的方法,实际上不包括在该语言中,而是包含在Cocoa框架中用于OS X,iOS应用开发。Cocoa框架中Foundation框架类库的NSObject类的alloc类方法,retain实例方法,release实例方法和dealloc实例方法。

        alloc与new方法都是生成并持有对象,copy方法利用基于NSCopying方法约定,由各类实现的copyWithZone:方法生成并持有对象的副本。与copy方法类似,mutableCopy方法利用基于NSMutableCopying方法约定,有各类实现的mutableCopyWithZone:方法生成并持有对象的副本。两者的区别在于,copy方法生成不可变的对象,而mutableCopy方法生成可变更的对象。这类似于NSArray类对象与NSMutableArray类对象的差异。用这些方法生成的对象,虽然是对象的副本,但同alloc,new方法一样,在“自己生成并持有对象”这点上没有改变。

        非自己生成的对象,自己也能持有,例如数组的array方法,字典的dictionary方法等。

        id obj = 【NSMutableArray array】;

        NSMutableArray类对象被赋给变量obj,但变量obj自己并不持有该对象。使用retain方法可以持有对象。

        自己持有的对象,一旦不再需要,持有者有义务释放对象。释放对象使用release方法。autorelease方法,可以使取得的对象存在,但自己不持有对象。autorelease提供这样的功能,是对象在超出指定的生存范围时能够自定并正确地释放(调用release方法)。autorelease把不立即释放的对象注册到autoreleasepool中(自动释放池,就像一个池子一样,存放了所有不立即释放的对象),autoreleasepool是OC中的一种内存自动回收机制,它可以延迟加入autoreleasepool中的对象release的时机。autoreleasepool的实现原理涉及到了runloop,底层也与C++有关,有兴趣的朋友可以自行搜索查资料研究了。

        对于用alloc/new/copy/mutableCopy方法生成并持有对象,或是用retain方法持有的对象,由于持有者是自己,所以在不需要该对象时需要将其释放。而由此意外所得到的对象绝对不能释放。倘若在应用程序中释放了非自己所持有的对象就会崩溃。例如自己生成并持有对象后,在释放完不再需要的对象之后再次释放。

相关文章

  • iOS内存管理1:引用计数

    iOS内存管理1:引用计数 引用计数: Objecttive-C使用引用计数来进行内存管理。然后,引用计数其实是不...

  • EffectiveObjective-C2.0 笔记 - 第五部

    5 内存管理 5.1 理解引用计数 1、引用计数 Objective-C 语言使用引用计数来管理内存,每个对象都有...

  • 目录

    第1章自动引用计数 1.1什么是自动引用计数 1.2内存管理/引用计数 1.2.1概要1.2.2内存管理的思考方式...

  • 读《Objective-C高级编程..》笔记

    第一章、自动引用计数 1、内存管理/引用计数 OC中通过引用计数来进行内存管理(其他的内存管理方式有垃圾回收等) ...

  • iOS 底层基础知识整理

    我所理解的内存管理,介绍一下内存管理。答:采用引用计数管理对象内存,当持有该对象,则引用计数加1,不需要了引用计数...

  • Obj-C高级编程--内存管理

    自动引用计数 自动引用计数:指内存管理中对引用采取自动计数的技术。 内存管理/引用计数 持有对象引起引用计数加...

  • 内存管理与自动引用计数—第一日

    自动引用计数 1.1 什么是自动引用计数 内存管理中对引用采用自动计数的计数 1.2 内存管理/引用计数 这一张举...

  • iOS内存管理-基本概念整理

    主要内容:1.内存区域划分2.内存管理/引用计数3.MRC手动管理引用计数4.ARC自动引用计数5.内存泄漏问题6...

  • Effective Objective-C 2.0笔记(四)

    第五章 内存管理 第29条:理解引用计数 OC使用引用计数管理内存,引用计数机制通过递增递减的计数器来管理内存。对...

  • iOS面试之内存管理大全

    内存管理内容如下: 内存布局 内存管理 数据结构 ARC/MRC 引用计数 弱引用 自动释放池 循环引用 1.内存...

网友评论

    本文标题:内存管理/引用计数(1)

    本文链接:https://www.haomeiwen.com/subject/cyhfuqtx.html