iOS复习笔记4:内存管理

一 基础原理
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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。