iOS 内存管理(基本概念及引用计数)
内存管理重要性
移动设备的内存极其有限,每个 APP 所占的内存都是有限的
下列行为就会增加一个 APP 的内存占用
创建一个 OC 对象
定义一个变量
调用一个函数或者方法
当 APP 所占用内存较多时,系统会发出内存警告,这时得回收一些不需要再次使用的内存空间,比如收一些不需要使用的对象、变量等
若果 APP 占用内存过大,系统会强制关闭 APP,造成闪退,影响用户体验
内存管理
内存管理:就是管理内存的分配和清除
内存管理涉及的操作有:
分配内存:比如创建一个对象,会增加内存占用
清楚内存:比如销毁一个对象,能减少内存占用
内存管理范围
任何继承 NSObject 的对象
对其他非对象类型无效(int char float double struct enum 等)
注:
为什么只有 OC 对象才需要进行内存管理的本质原因
OC 对象存放于堆里面(堆内存系统不会自动释放,需要手动释放)
非 OC 对象一般放在栈里面(栈内存会被系统自动回收释放)
堆和栈
栈(操作系统):由操作系统自动分配释放空间,存放函数的参数值,局部变量的值等,其操作方式类似于数据结构中的栈的先进后出
堆(操作系统):一般由程序员分配释放空间,若程序员不释放,程序结束时可能由 OS 回收,分配方式类似于链表
引用计数器
OC 语言使用引用计数来管理内存,每一个对象都有一个可以递增递减的计数器,如果引用这个对象,那么这个对象的引用计数递增,如果不用了,那么这个对象引用计数递减,直到引用计数为 0,这个对象就可以销毁了
引用计数器的作用
表示对象被引用的次数
查看某对象的引用计数调用
- (NSUInteger)retainCount
当使用
alloc
、new
、copy
创建一个对象时,对象的引用计数器默认为 1当没有任何人使用这个对象时,系统才会回收这个对象
当对象的引用计数器为 0 时,对象占用的内存才会被回收
如果对象的引用计数不为 0,这个对象占用的内存就不可能被回收(除非整个程序已经退出)
引用计数器的原理
给对象发送一条
retain
消息,这个对象的引用计数值+1给对象发送一条
release
消息,这个对象的引用计数值-1给对象发送
retainCount
消息,可以获得当有对象的引用计数注:<br>release
并不代表销毁或回收对象,仅仅是计数器-1
属性存取方法中的内存管理(retain、copy、assign)
readonly
: 只会生成getter
方法readwrite
:既会生成getter
也会生成setter
方法,默认什么不写就是 readwritegetter
:可以给生成的getter
方法起一个名字setter
:可以给生成的setter
方法起一个名字retain
: 会自动帮我们生成setter
方法内存管理的代码assign
:不会帮我们生成setter
方法内存管理的代码,仅仅只会生成普通的getter/setter
方法,默认什么都不写就是assign
nonatomic
:多线程中使用,性能低(默认)atomic
:多线程中使用,性能高
dealloc 方法
当一个对象的引用计数器值为 0 的时候,这个对象即将被释放,其占用的内存被系统收回
对象即将被销毁时系统会自动给对象发送一条
dealloc
的消息(因此,从dealloc
方法有没有被调用就可以判断出对象是否被销毁)dealloc
方法重写一般重写
dealloc
方法,在这里释放相关资源(移除监听者、移除 coreFoundation 对象等等)在 MRC 下,一旦重写
dealloc
方法,就必须调用[super dealloc]
,并且放在最后调用使用注意
不直接调用
dealloc
不要在
dealloc
方法中调用其他方法一旦对象被回收了,它占的内存就不再可用
版权声明: 本文为 InfoQ 作者【NewBoy】的原创文章。
原文链接:【http://xie.infoq.cn/article/acb27a9f73c35e4ca11b7270c】。文章转载请联系作者。
评论