课堂笔记:
- 只有OC对象才需要进行内存管理的本质原因是OC对象存放在堆里面,非OC对象一般放在栈里面(栈内存会被系统自动回收)
- 当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1
- 僵尸对象:已经被销毁的对象(不能再使用的对象)
- 野指针:指向僵尸对象(坏内存)的指针,给野指针发消息会报EXC_BAD_ACCESS错误
- 空指针:没有指向储存空间的指针(里面存的是nil,也就是0),给空指针发消息是没有任何反应的
- 为了避免野指针错误的常见方法:在对象被销毁之后,将指向对象的指针变为空指针
- 一旦重写dealloc方法,就必须调用[super dealloc],并且必须放在最后面调用
引用计数器的常见操作
- 给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身)
- 给对象发送一条release消息,可以使引用计数器值-1
- 给对象发送retainCount消息,可以获得当前的引用计数器值
注意:release并不代表销毁/回收对象,仅仅是引用计数器-1
-
要想手动调用retain、release等方法,就必须关闭ARC功能 在build Setting下搜索automatic r就可以
-
默认情况下,Xcode是不会管僵尸对象的,使用一块被释放的内存也不会报错,为了方便调试,应该开启僵尸对象监控
@property参数
- 控制set方法的内存管理
1.retain:release旧值,retain新值(OC对象)
2.assign:直接赋值,不做任何内存处理(默认,用于非OC对象类型)
3.copy:release旧值,copy新值(一般用于NSString *) - 控制需不需生成set方法
1.readwrite:同时生成set方法和get方法(默认)
2.readonly:只会生成get方法 - 多线程管理
1.atomic:性能低(默认)
2.nonatomic:性能高
set方法的内存管理
-(void)setCar:(NSString *)car
{
if (car != _car) {
//对当前正在使用的车(旧车)做一次release
[_car release];
//对新车做一次retain操作
_car = [car retain];
}
}```
***
@class和#import的区别
- 作用上的区别:#import会包含引用类的所有信息(内容),包括引用类的变量和方法。@class仅仅是告诉编译器有这么一个类,具体这个类里面有什么信息,完全不知
- 效率上的区别:如果有上百个头文件都#import了用一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动,后面引用到这个文件的所有类都需要重新编译一遍,编译效率非常低。相对来说,使用@class方式就不会出现这个问题了