内存管理
iOS开发中,对堆内存的创建、销毁(释放),就叫做内存管理。
内存管理有两种方式:
MRC:手动内存管理。
ARC:自动内存管理。
一,
内存管理的机制:
每个对象都有自己的引用计数器。在MRC内存管理模式下,引用计数器计算机是无法自动操作的。
向对象发送[对象 retainCount];该对象引用计数器的值
当向对象发送alloc、copy、new消息的时候,该对象的引用计数器会自动设置为1.
当不再使用对象的时候的时候,会发送release消息,通知引用计数器”减”1。
当一个对象的引用计数器的值为0时,”系统”会”自动”销毁该对象,并回收该内存空间。
当对象销毁的时候,会”自动”发送dealloc消息。
//重写父类的dealloc方法
- (void)dealloc{
NSLog(@"对象销毁了");
[super dealloc];
}
二,在xcode5以后,都是强制使用ARC内存管理的。
需要手动改成MRC内存管理:
项目->BuildSetting->All->ARC->OC language->OC ARC=NO;
强制操作系统立刻回收内存:
edit scheme->Diag…->Enable Zombie Objects
三:
引用计数器:用来记录对象被引用的次数,每个对象天生就有一个引用计数器。
Reference Counting
引用的次数:一个对象被几个引用使用。
@autoreleasepool {
//分配了一个堆空间
TRStudent *stu = [[TRStudent alloc]init];
TRStudent *stu2 = stu;
//查看该对象的引用计数器
NSUInteger count = [stu retainCount];
NSLog(@"count:%lu",count);
[stu study];
NSLog(@"stu:%p stu2:%p",stu,stu2);
//释放堆空间
[stu release];//free()
//[stu2 study];
}
TRStudent *stu = [[TRStudent alloc]init];
TRStudent *stu2 = stu;
内存管理使用不当:通过引用使用一个以经不存在的对象(堆空间),会出现异常、crash(Exception)。
解决:1.野指针问题,使用空指针来解决野指针问题。
对象不在使用的时候,忘记发送release消息,内存溢出(内存浪费)(内存泄露)。
四: 多个引用使用同一个对象,需要retain操作。
解决:1.谁创建的内存(谁加1),谁就有责任减1。
@autoreleasepool {
//RC:1
TRStudent *stu = [TRStudentnew];
//两个引用共用一个对象
TRStudent *stu2 = stu;
//通知引用计数器加1
[stu2 retain];
NSUInteger count = [sturetainCount];
NSLog(@"count:%lu",count);
[stu2 study];
//谁通知引用计数器加1谁有责任做减1操作
[stu release];//RC:2-1 = 1
[stu2 study];
[stu2 release];//RC:1-1 = 0
}
五:对象当中有属性为对象:
#import <Foundation/Foundation.h>
#import "TRBook.h"
@interface TRStudent :NSObject
//本质属性
//1.书的实例变量
{
TRBook *_book;
}
//2.setter/getter book
-(void)setBook:(TRBook*)book;
-(TRBook*)book;
-(void)study;
@end
六:声明式属性解决加1操作,但减1操作依然需要手动处理。(也就是对象当中有属性为对象:这种的方式内存管理可以写为下面这种形式)
@implementation TRStudent
/*
-(void)setBook:(TRBook*)book{
//第二种情况多次读书的问题
if (_book==nil) {//第一次读书
_book = book;
[_book retain];
}else{
[_book release];
_book = book;
[_book retain];
}
// 第一种情况属性如果是对象类型存在内存隐患
//_book = book;//真正赋值的时候在这里
//[_book retain];//有责任做加1操作
}
-(TRBook*)book{
return _book;
}
*/
-(void)study{
NSLog(@"学生具有学习的能力看书 book:%d",self.book.price);
}
//重写
- (void)dealloc{
[_bookrelease];//当不再使用书的时候,有责任减1
NSLog(@"Student对象销毁了");
[superdealloc];
}
七:自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来
回收
统一释放
自动释放池本事销毁的时候,池子里面所有的对象都会做一次release操作
@autoreleasepool {//开始
TRStudent *stu = [[[TRStudentalloc]init]autorelease];
//[stu ...];
//[stu autorelease];
/*
TRStudent *stu = [TRStudent student];
NSObject *obj = [stu obj];
*/
NSLog(@"自动释放池末尾");
}//结束当自动释放池结束的时候,会向池中的对象发送release消息
NSLog(@"程序的末尾");
return0;