一 基础原理
1 为什么需要内存管理
因为移动设备内存有限,每个app所占用的空间有限。
当app占用内存空间过多时,系统会发出内存警告,这是回收一些不在使用的内存。
例如:不再使用的类对象和实例。
2 管理对象
任何继承自NSObject类的对象
3 内存区域
堆:主动分配空间,需要管理
栈:局部变量,自动管理
例如:
int a = 1;
Person* p = [[Person alloc] init];
a,p都放在栈区
Person分配的空间在堆区
二 引用计数
1 定义
每个OC对象都有一个引用计数,是一个4个字节的整数,表示“被引用的次数”。
可以使用retainCount方法查看一个对象的引用计数。
2 作用
一个对象创建(alloc/new/copy)时为1;
引用计数变为0时,会被系统回收。
引用计数变不为0时,它占用的内存不可能被回收,除非整个程序退出。
3 引用计数操作
retain +1
release -1
4 对象销毁
一个对象引用计数为0时,其占用的内存会被系统销毁。
被销毁时,系统会向对象发送一条dealloc消息。
因此,一般需要重写dealloc方法,首先调用父类的dealloc,然后释放自己的资源。
对象销毁后,其内存被回收,继续使用会导致程序crash(野指针)。
*dealloc不能手动调用
示例
@interface Person @property int m_nAge; @end @implementation Person - (void)dealloc { NSLog(@"dealloc");// 验证对象是否被回收 [super dealloc]; } @end #import <Foundation/Foundation.h> int main() { // 默认为1 Person* p = [[Person] init]; NSUInteger count = [p retainCount]; NSLog(@"retainCount == %ld", count); // +1,变为2,retain返回值为对象本身 [p retain]; // -1,变为1 [p release]; // -1,变为0,被回收,被回收之后p变为野指针,指向的对象变为僵死对象 // 不能对僵死对象发送任何消息,包括retain [p release]; // 报错:EXC_BAD_ACCESS // p.m_nAge = 10 // 防止野指针错误,因为给nil对象发送消息不报错,只有警告 p = nil; // 开启僵尸检查之后才报错:setXXX,message sent to deallocated instance p.m_nAge = 10 return 0; }
使用被回收的对象报错:EXC_BAD_ACCESS,访问了一块被回收的内存,即野指针错误
三 总结
1 基本方法
retain
release
retainCount
dealloc
2 概念
僵尸对象:所占用内被回收的对象:
野指针:指向僵尸对象
空指针:没有指向任何地址,存储的地址为0/NULL/nil
时间: 2024-10-13 17:19:42