iOS内存管理(转载)

内存管理

堆:需要手动释放。

栈:系统自动管理。

所谓内存管理,就是对内存进行管理,涉及的操作有:

  • 分配内存 :比如创建一个对象,会增加内存占用
  • 清除内存 :比如销毁一个对象,能减小内存占用

内存管理的管理范围

  • 任何继承了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
2
3
4
5
6
7
8
9
10
11
- (void)setCar:(Car*)car
{
if(car!= _car)
{
// 对当前正在使用的车(旧车)做一次release
[_car release];

// 对新车做一次retain操作
_car=[car retain];
}
}

dealloc方法内存管理

1
2
3
4
5
6
7
8
- (void)dealloc
{
//当人不在了,代表不用车了
// 对车做一次release操作
[_car release];
//调用dealloc方法时候一定要调用父类的dealloc的方法
[super dealloc];
}

@class和#import的区别

作用上的区别

  • import会包含引用类的所有信息(内容), 包括引用类的变量和方法
  • @class仅仅是告诉编译器有这么一个类,具体这个类里有什么信息, 完全不知道。

效率上的区别

  • 如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,编译效率非常低
  • 相对来讲,使用@class方式就不会出现这种问题

转载自内存管理笔记