1 内存分区 1) 栈区:局部变量 2) 堆区:动态分配的内存空间 3) BSS:未初始化的全局变量和静态变量 4) 数据区;初始化的全局变量和静态变量,以及字符串常量 5) 代码区;代码 2 内存管理的范围 管理任何继承NSObject的对象。 3 对象的所以权和引用计数 任何对象都可能拥有一个或者多个所有者。只要对象还有一个所有者,它就会继续存在。 所有权策略 任何自己创建的对象都归自己所有。 可以使用alooc 和new创建对象也可以使用retain获得对象的所有权, 引用计数 每个对象都有自己的引用计数器表示对象被引用的次数。对象刚被建立时 计数为1 .当计数为0 的时候,对象被释放。 当对象指向nil时 不会回收,因为没有给对象分配空间。 对引用计数器的操作 1)retain +1 返回对象本身 2)release -1 不一定被释放。 3)retainCount 获取对象引用计数 %ld 或者%lu 对象的销毁 当引用计数为0的时候,对象会被销毁,此时系统会向对象发送 dealloc消息 释放相关资源。 4 手动内存管理 重写dealloc方法 -(void)dealloc{ //先释放子类对象的内存空间 [super dealloc]; //后父类完成自己dealloc方法 } 注意 不要自己手动调用dealloc 方法,系统会自动调用。 5 内存管理的原则 1) 如果retainCount 不为0 不能回收 2) 使用时 计数 +1 retain 3) 不再使用时 计数-1 release 4) 谁创建谁release alloc newcopy 5) 谁retain 谁release 6 内存泄漏 栈区的指针释放之前没有释放堆区的对象空间 单对象野指针 定义的指针没有初始化 或 指向的空间已经被释放 指针还去调用。 僵尸对象 已经被释放的对象。僵尸对象不能再使用。僵尸对象不能通过retain复活。 对象释放以后将对象指向 nil 可以避免僵尸对象。 内存泄漏 1) 创建之后没有release 2) retain之后没有release 3) 不当的使用 nil 对象还有所有者的时候把对象指向了 nil。 4) 函数中不当使用 自己作为自己方法的参数。 多个对象的野指针 A对象已经释放B对象还调用A对象 注意 A B两个对象的释放顺序。 7 多对象管理时set 方法的内存管理 Person 类中有成员变量 Car类型的 _car Person 方法中使用 _car set方法优化 -void setCar:(Car car){ if(_car ! =car){ //判断两次传递的是否是同一个对象如果不是 [_car release]; //先将之前的对象进行释放 _car=[car retain]; //之后再将新的对象的计数+1 } } 在Person的dealloc方法 中将 _car进行释放一次。 注意 基本数据类型:直接赋值 对象类型:如果A类中有B类对象(关联关系) set 方法需要先release 旧值在retain新值 还要判断新值和旧值是否是同一个对象。
|