无论是 ios 还是 android 中,系统对每个程序运行时内存的占用都有一个限制,默认都是几十 M 左右大小,当程序占用的内存的大小超过限制时,程序可能就会被强制退出。
拿 iphone4 来说,当程序内存占用超过 40M 时,会出现内存警告,当内存占用达到 45M,还会再一次内存警告,对于以上两次警告如果不做出释放内存操作,当达到 120M 时,系统会自动 kill 掉程序。
在内存中,分为堆和栈,栈中主要存放变量,堆中主要存放对象。栈中的东西是系统自动回收的,当一个变量使用完毕后,存放在栈中的东西会立刻被回收。但堆中存储的东西是不会随便回收的。内存管理管理的是堆空间。OC绝大部分都在堆空间,我们必须要进行内存管理,内存管理的作用时解决内存泄漏(忘记释放),内存崩溃(提前释放、过早释放、多释放)。
每个 OC 对象里都有一个引用计数器,是一个整数,用来统计正在被引用多少次,每个引用计数器占用 4 个字节,对象刚刚创建时引用计数器默认为 1。如果 OC 对象引用计数器为 0 时,系统就可以回收这个对象了。引用计数器的操作:
(1) 给对象发送一条 retain 消息,可以使引用计数器值+1(retain 方法返回对象本身)
(2) 给对象发送一条 release 消息,可以使引用计数器值-1
(3) 给对象发送一条 retainCount 消息,可以获得当前的引用计数器值
对象的销毁:
(1) 当一个对象的引用计数器的值为 0 时,那么它将被销毁,其占用的内存会被系统回收。
(2) 当一个对象被销毁时,系统会自动向对象发送一条 dealloc 消息
(3) 一般会重写 dealloc 方法,在这里释放相关资源,dealloc 就像对象的遗言。
(4) 一旦重写了 dealloc 方法,就必须调用[super dealloc],并且放在最后面调用。
(5) 不要直接调用 dealloc 方法。
(6) 一旦对象被回收了,它占用的内存不再可用,坚持使用就会导致程序崩溃(指针错误)。
概念:
僵尸对象:所占用的内存已经被回收的对象,僵尸对象不能再使用野指针:指向僵尸对象的指针,给野指针发送消息会报错空指针:没有指向任何东西的指针(存储的东西是 nil、null、0),给空指针发送消息不会报错。
【备注】nil 与 null 不同,null 是一个宏定义,值为 0,nil 表示无值,任何变量在没有赋值之前都是 nil,对于真假判断,只有 nil 和 false 表示假,其他均为真。
官方术语:
Basic Memory Management Rules
The memory management model is based on object ownership. Any object may have one or more owners. As long as an object has at least one owner, it continues to exist. If an object has no owners, the runtime system destroys it automatically. To make sure it is clear when you own an object and when you do not, Cocoa sets the following policy:
- You own any object you create
- ,
newObject
, ormutableCopy
). - You can take ownership of an object using retain
retain
- in two situations: (1) In the implementation of an accessor method or an
init
method, to take ownership of an object you want to store as a property value; and (2) To prevent an object from being invalidated as a side-effect of some other operation (as explained in Avoid Causing Deallocation of Objects You’re Using). - When you no longer need it, you must relinquish ownership of an object you own
- message or an
autorelease
message. In Cocoa terminology, relinquishing ownership of an object is therefore typically referred to as “releasing” an object. - You must not relinquish ownership of an object you do not own
This is just corollary of the previous policy rules, stated explicitly。
内存管理原则理解:
当我们程序猿自己用alloc/new/copy/mutableCopy/retain开头的函数把对象地址给一个新的指针变量(拥有了对象的绝对使用权),指针用完对象之后,不再使用对象的时候,那么指针应该立即release或者autorelease(放弃绝对使用权)。每个指针只需要管理好自己就可以了,不需要管理其他的指针(个人顾个人原则),释放之后的指针就不要再操作原来的对象了。
结论
1.只有程序员自己写出来alloc/new/copy/mutableCopy/retain这些函数,用完指针之后要对应出现一个release/autorelease。如果没有上面的函数,就不需要管
2.什么时候retain?当一个对象多出一个指针指向的时候。