1、什么是内存管理
** 移动设备的内存及其有限,每一个app所能占用的内存也有限的
** 当app所占用的内存较多时,系统会给app发送内存警告,这时,app需要回收一些不再使用到的内存空间,比如回收一些不需要使用的对象。
** 管理范围,任何继承了NSObject的对象,对其他的基本数据类型(int 、char、 float、double、struct、enum等)无效
2、OC对象的基本结构
** 每个OC对象都有自己的引用计数器,是一个整数, 表示对象被引用的次数,
** 每个OC对象内部专门有4个字节的存储空间来存储引用计数器
3、引用计数器的作用
** 当调用 alloc 、new 或者 copy 创建一个对象时,新创建对象的引用计数器默认为1
** 当一个对象的的引用计数器的值为0时,对象所占用的那块内存空间就会被系统回收,换句话说,如果对象的引用计数器不为0,那么在程序运动的过程中,这个对象所占用的内存空间都不回被系统回收,除非整个程序退出。
4、引用计数器的操作
** 给对象发送 retain 消息,可以使对象的引用计数器+1,并且返回对象本身
** 给对象发送一条release 消息, 可以使对象的引用计数器-1 ,并不是就释放对象,没有返回值
** 可以通过给对象发送retainCount消息来获对象当前的引用计数器的值
** 对象被释放的唯一标识是 对象的 retainCount 的值为 0。
新建Person对象
Person.h文件
@interface Person : NSObject
@property int age;
@end
Person.m文件
// 当一个Person对象被回收的时候,就会自动调用这个方法
- (void)dealloc
{
NSLog(@"Person对象被回收");
self = nil;
// super的dealloc一定要调用,而且放在最后面
[super dealloc];
}
#import "Person.h"
int main()
{
// 1
Person *p = [[Person alloc] init];
NSLog(@"计数器:%ld", [p retainCount]);
// 2 retain方法返回的是对象本身
[p retain];
// 1
[p release];
// 0 野指针:指向僵尸对象(不可用内存)的指针
[p release];
// [p retain]; // 对象释放不能复生, 已经被释放的对象不能在发
//OC不存在空指针错误,给空指针发送消息,不报错
// p = nil; // 指针p变成空指针
// [nil release];
// 野指针错误: EXC_BAD_ACCESS : 访问了一块坏的内存(已经被回收、已经不可用的内存)
[p release];
[p release];
/* 打开僵尸对象检测开关 */
// -[Person setAge:]: message sent to deallocated instance 0x100109a10
// 给已经释放的对象发送了一条-setAge:消息:
p.age = 10;
//[p setAge:10];
return 0;
}
5、几个重要的概念
** 将是对象:所占用内存已经被回收的对象,僵尸对象不能再使用
** 野指针:指向僵尸对象(不可用内存)的指针,给野指针发送消息会报错(EXC_BAD_ACCESS)
** 空指针:没有指向任何东西的指针(存储的东西是nil、NULL、0),给空指针发送消息不会报错
总结:
** retain :计数器+1,会返回对象本身
** release :计数器-1,没有返回值
** retainCount :获取当前的计数器
** dealloc方法
* 当一个对象要被回收的时候,就会调用
* 一定要调用[super dealloc],这句调用要放在最后面