内存管理
【内存管理】
内存管理就是确保申请的内存能够得到合理及时的释放
1、忘记释放一个堆空间,称为【内存泄漏】
2、使用已经释放的内存,称为【提前释放】
3、多次释放同一堆空间,称为【重复释放】
【困境】
1、释放一个堆空间,需要确保所有指向该空间的指针都不再使用
2、释放一个堆空间,需要确保指向同一空间的指针只释放一次
3、模块化操作时,哪个模块负责释放将成为巨大的难题
4、多线程操作时,没有办法确定哪个线程最后结束
【解决】
采用类似于聊天室的计数方式。第一个人开始聊天时创建聊天室,并将计数值设置为1。当多一个人加入聊天室时,将计数值加1;当一个人离开聊天室时,将计数值减1,计数值减到0时释放聊天室。
其实就是确保聊天室中的人数与计数值相等。
【结论】
在创建对象时将其引用计数设置为1,当多一个指针指向该对象时将计数值加1;当少一个指针指向对象时将计数值减1,计数值减到0时释放对象。
其实就是确保指向对象的指针数等于计数值
一、手动内存管理
Manual Reference Counting,简称MRC
【关闭ARC】
1、工程 —> gar
2、Yes —> No
【相关方法】
1、获取对象的引用计数
NSUInteger count = [dog retainCount];
2、使对象的引用计数加1
//将对象的引用计数加1,并返回该对象的地址
//平白无故的retain是不允许
JYDog *dog2 = [dog retain];
3、使对象的引用计数减1,减到0时释放对象
[dog2 release];
4、析构方法
//析构方法,在对象释放时自动调用
- (void)dealloc
{
NSLog(@"dog 对象即将释放");
[super dealloc];
}
【黄金法则】
1、凡是用alloc/new/retain/copy(开头)/mutableCopy(开头)等创建的对象,
都需要调用release/autorelease进行释放。
2、谁写alloc,谁写release;哪个类创建,哪个类释放
【注意事项】
1、对象的子对象需要在析构方法中释放
2、在指针转移时,应先释放就对象,然后指向新对象
3、数组的内存管理,见【数组的内存管理】demo
4、[[JYClass alloc] init] <==> [JYClass new]
5、(mutable)copy基本上只有在NSString上
6、字符串类型的内存计数器为-1
【自动释放】
以前不是关键字,是一个类NSAutoreleasePool,可以将需要释放的对象存放在其中(类似于一个数组),等池释放时将其中的对象各释放一次,也叫延迟释放。
现在为了配合ARC改成关键字@autoreleasepool
【说明】
1、一定要结合自动释放池
2、对象的引用计数不会直接减1,等池释放时才会减1
【自动释放原则】—— 非用不可的时候
1、类方法创建的对象
2、getter方法中[[_name retain] autorelease]
二、自动内存管理(后面阶段)
Automatic Reference Counting,简称ARC
1、将MRC的文件转换为ARC的
2、MRC和ARC共存(混编)
【copy】
NSString *str1 = @"123456";
NSString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
//copy和mutableCopy拷贝出来的对象与原对象无关
//copy拷贝的对象都是不可修改的
//mutableCopy拷贝的对象都是可以修改的