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

        本文学习方向与部分内容借鉴《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方法持有的对象,由于持有者是自己,所以在不需要该对象时需要将其释放。而由此意外所得到的对象绝对不能释放。倘若在应用程序中释放了非自己所持有的对象就会崩溃。例如自己生成并持有对象后,在释放完不再需要的对象之后再次释放。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352