内存管理
堆:需要手动释放。
栈:系统自动管理。
所谓内存管理,就是对内存进行管理,涉及的操作有:
- 分配内存 :比如创建一个对象,会增加内存占用
- 清除内存 :比如销毁一个对象,能减小内存占用
内存管理的管理范围
- 任何继承了NSObject的对象
- 对其他非对象类型无效(int、char、float、double、struct、enum等)
只有OC对象才需要进行内存管理的本质原因
- OC对象存放于堆里面
- OC基础类型一般放在栈里面(栈内存会被系统自动回收)
引用计数器的常见操作
给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)
给对象发送一条release消息,可以使引用计数器值-1
给对象发送retainCount消息,可以获得当前的引用计数器值
需要注意
的是: release并不代表销毁\回收对象,仅仅是计数器-1。
空指针\野指针
僵尸对象:已经被销毁的对象(不能再使用的对象)
野指针:指向僵尸对象(不可用内存)的指针
给野指针发消息会报EXC_BAD_ACCESS错误空指针:没有指向存储空间的指针(里面存的是nil,也就是0)
- 给空指针发消息是没有任何反应的。
- 为了避免野指针错误的常见办法
- 在对象被销毁之后,将指向对象的指针变为空指针
delloc方法注意细节
当一个对象的引用计数器值为0时
- 这个对象即将被销毁,其占用的内存被系统回收
- 系统会自动给对象发送一条dealloc消息(因此,从dealloc方法有没有被调用,就可以判断出对象是否被销毁)
dealloc方法的重写
- 一般会重写dealloc方法,在这里释放相关资源,dealloc就是对象的遗言
- 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用
注意:
- 不能直接调用dealloc方法
- 一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)
内存管理原则
- 谁创建谁release:如果你通过alloc、new或[mutable]copy来创建一个对象,那么你必须调用release或autorelease。
- 谁retain谁release:只要你调用了retain,就必须调用一次release。
总结
有加就有减
曾经让对象的计数器+1,就必须在最后让对象计数器-1
set方法的内存管理
1 | - (void)setCar:(Car*)car |
dealloc方法内存管理
1 | - (void)dealloc |
@class和#import的区别
作用上的区别
- import会包含引用类的所有信息(内容), 包括引用类的变量和方法
- @class仅仅是告诉编译器有这么一个类,具体这个类里有什么信息, 完全不知道。
效率上的区别
- 如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,编译效率非常低
- 相对来讲,使用@class方式就不会出现这种问题