17 - 内存管理方案之MRC和ARC

OC底层原理探索文档汇总

在上文我们知道了内存的五大区域组成,接下来了解对于内存的管理。

内存管理其实就是管理堆

因为分配堆的空间大小不确定,而且它的生命周期不确定,需要人为管理。
栈的数据虽然也是运行时临时分配的,但是其会在方法调用结束后自动回收,所以无需关注。
全局区/静态区和常量区、代码区的生命周期都是APP运行的整个过程,所以系统会在APP运行结束后自动回收。

因此我们常说的内存管理很大程度上就是指管理堆

引用计数的认识

iOS提供引用计数方式来管理内存,当计数器为0时,就表示这个对象就成为了垃圾对象,系统会在合适的时候进行回收。

引用计数的时机:

  • 新创建一个引用类型对象(alloc/new/copy/mutableCopy),计数为1
  • retain的+1操作(只要被别人用到了,就要+1)
    • 将对象赋值给其他变量
    • 将对象赋值给其他实例变量或属性
    • 将对象加入到集合中
    • 将对象作为参数传递
    • 将对象作为返回值
  • release的-1操作
    • 将变量赋值为nil或其他值
    • 将属性或实例变量设置为nil或其他值
    • 实例变量或属性所在的对象被释放
    • 参数或局部变量离开函数时
    • 将对象从集合中删除

文艺的解释

记得在《寻梦环游记》里对于一个人的死亡是这样定义的:当这个这个世界上最后一个人都忘记你时,就迎来了终极死亡。类比于引用计数,就是每有一个人记得你时你的引用计数加1,每有一个人忘记你时,你的引用计数减1,当所有人都忘记你时,你就消失了,也就是从内存中释放了。

如果再深一层,包含我们后面要介绍的ARC中的强引用和弱引用的话,那这个记住的含义就不一样了。强引用就是你挚爱的亲人,朋友等对你比较重要的人记得你,你的引用计数才加1。

而弱引用就是那种路人,一面之缘的人,他们只是对你有一个印象,他们记得你是没有用的,你的引用计数不会加1。当你挚爱的人都忘记你时,你的引用计数归零,你就从这个世界上消失了,而这些路人只是感觉到自己记忆中忽然少了些什么而已。

MRC手动引用计数

早期需要手动管理,也就是手动对引用计数进行加减,现在都是在系统自动进行引用计数的管理。

注意:

  • 原则:计数加一和减一的调用次数一定要匹配,
  • 计数为0时,系统自动调用dealloc方法来回收
  • 内存回收后,只是代表着这个空间可以分配给别人,而不是真的空间被删掉,或者内存数据被删掉
  • 在MRC模式下,必须遵守:谁创建,谁释放,谁引用,谁管理

ARC自动引用计数

ARC简单来说就是系统帮我们自动加上release(autoRelease)和retain方法,不需要手动添加。

注意:当对象没有强指针引用时,会被回收,注意这里一定要是强指针,因为有弱指针,也会被立即回收

所有权修饰符

使用ARC时,处理对象类型或id类型时,一定要加上所有权修饰符,没有加的话就默认是__strong,即强引用

  • __strong:默认所有权修饰符,表示强引用,会增加引用计数
  • __weak:表示弱引用,不会增加引用计数,只会在对象的弱引用计数表中进行计数。
    • 可用于解决循环引用问题。
    • 当对象被释放前会通过判断是否存在弱引用表,所有指向它的弱引用都会被释放掉,这样可以避免野指针问题。
    • 不可以修饰基本数据类型,只能修饰引用类型
    • iOS5以上版本可使用
  • _unsafe_unretained:与__weak类似,区别在于,不能在对象被释放后自动将引用设置为nil,iOS5以下版本使用,所以无需关注
  • __autoreleasing:
    • 它可以将对象注册到autorelease,也就等同于在MRC下调用对象的autorelease方法
    • 在ARC中,可以在@autorelease{}中来使用
    • 一般来说会自动添加,不用显式使用__autorelease

属性修饰符

分别查看不同的属性修饰符它们所代表的所有权修饰符是什么

  • assign:__unsafe_unretained
    • 因此他不能在对象被释放后自动将引用设置为nil,所以以后只能用在基本数据类型,而不能用在引用类型
  • retain:__strong
    • retain也会增加引用计数
  • strong:__strong
    • 可以用在ARC上对属性进行修饰,作为强引用
  • copy:__strong
    • copy的所有权也是__strong,所以也会进行强引用
    • 区别在于会重新开辟一个空间,指向该引用,新对象引用+1,原来的对象并不会引用+1
  • weak:__weak
    • 在ARC中使用,作为弱引用。
  • __unsafe_unretained:__unsafe_unretained
    • 不要用,仅了解,因为只在iOS5以下版本才会使用

默认的关键字为:
引用类型:@property (atomic,readWrite,strong) UIView *view;
基本数据类型:@property (atomic,readWrite,assign) int *aa;

野指针和僵尸对象

野指针

指向一个已经被删除的对象或者访问受限内存区域的指针就是野指针

注意:野指针不是nil指针,而是指向了垃圾内存的指针

野指针的场景:

  • 对象释放后,指针没有置空
    • 使用unsafe_unretained修饰符,对象释放后,没有手动置为nil
    • KVO没有移除观察者
  • 对象提前释放
    • 异步函数中block使用的self没有强引用,导致外部已经释放掉,但是里面还在使用
  • 对象多次释放
    • 多个线程同时对某个对象赋值但没有加锁,就可能多次release。

僵尸对象

一个已经被释放掉的对象就是僵尸对象
一个OC对象的引用计数为0,调动dealloc后释放之后,就是僵尸对象。
一个对象虽然被释放掉了,但是数据依然在内存中,所以如果通过野指针去访问僵尸对象,一旦这个僵尸对象的内存已经被分配给其他人了,就会出错。

为什么不开启僵尸对象检测?
这样每次通过指针访问对象的时候都会检查是否为僵尸对象,这样很影响效率

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

推荐阅读更多精彩内容