4.内存管理

一、IOS内存管理

1、内存管理范围:任何继承了NSObject的对象,对基本数据类型无效。

2、内存管理原理:

(1)每个对象内部保存了一个与之相关联的整数,称为引用计数器。

(2)当使用alloca、new或者copy创建一个对象时,对象的引用计数器被设置为1.

(3)当给对象发送一条retain消息时,引用计数器加。

(4)当给对象发送一条release消息时,引用计数器减1。

(5)当对象的引用计数器为0时,该对象将被销毁,其占用的内存将被系统回收,OC也会自动向对象发送一条dealloc消息。一般会重写dealloca方法来释放相关资源,一定不要直接调用dealloca方法。

(6)可以给对象发送retainCount消息获得当前的引用计数器的值。


用于理解内存管理的实例:

1.Book类:

#import <Foundation/Foundation.h>
@interface YtsBook : NSObject
{
int _ID;
}
@property int ID;
-(id)initWithID:(int)_ID;
@end

#import "YtsBook.h"
@implement YtsBook:
@synthesize ID = _ID;
-(id)initWithID:(int)ID:
{
	_ID=ID;
}
@end

2.Student类:

#import <Foundation/Foundation.h>
//#import "YtsBook.h"
@class YtsBook;	//@class声明需用到YtsBook类
@interface YtsStudent : NSObject
{
	YtsBook *_book;
}
@property YtsBook *book;
@end

#import "YtsStudent.h"
#import "YtsBook.h"
@implement YtsStudent:
@synthesize book = _book;
-(void)setBook:(Book *)book		//在OC2.0以上,一般都是用@property的声明列表来代替这种方法。
{
	if(_book!=book)	//加上判断,预防重复复制
	{
		[_book release];	//释放旧值
		_book = [book retain];	//先retain,再赋值
	}
}

-(void)dealloc
{
	[_book release];	//由于赋值时做了retain,这里要负责将其release
	[super dealloc];
}

3. main.m

int main (int argc, const char * argv[]) 
{
	@autoreleasepool{
		YtsStudent *student = [[YtsStudent alloc] init];	//student引用计数器为1
		YtsBook *book = [[YtsBook alloc] initWithID:100];	//book引用计数器为1.
		student.book = book;	//book引用计数器为2
		[book release];	//book引用计数器为1
		[student release];	//此时book引用计数器为0,student引用计数器为0
	}
}

二、内存自动释放

1、自动释放池原理

(1)autorelease pool的真名是NSAutoreleasePool,在新建一个项目时,编译器会默认创建一个自动释放池。

(2)NSAutoreleasePool内部包含一个可变数组(NSMutableArray),用于保存声明为autorelease的对象。

(3)如果一个对象声明为autorelease,则系统就将这个对象加入到该数组中。

(4)当NSAutoreleasePool自身在销毁时,会遍历一遍该数组,release数组中的每一个成员。

实例:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
YtsStudent *student = [[[YtsStudent alloc] init] autorelease];	//设置为autorelease
YtsBook *book = [[[Book alloc] init] autorelease];	//设置为autorelease
student.book = book;
[pool release];

2、自动释放池做法

因为标记为autorelease的对象只有在自动释放池被销毁时才被release,当有大量标记为autorelease的对象时,就会存在内存故障。 所以我们经常手动定义一个NSAutoreleasePool,通过控制该池的销毁达到及时释放内存的目的。

 创建自动释放池的方法为:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

 销毁自动释放池的方法为:[pool release];

 3.当一个对象被声明为autorelease时,它将被加入到最新创建的自动释放池中。


三、内存管理口诀

 1. 通过alloc、new或copy创建的对象,那么必须调用release或autorelease。

 如果在类的某函数中alloc生成一个对象,那么必须在类的dealloc方法中release该对象,或者alloc和init该对象时就声明autorelease。

 注意:实现NSCopying的initWithZone方法里边,不要对创建的对象做autorelease或者release。

 2. 除了alloc、new或copy之外的方法创建的系统自带的类的对象都已被声明了autorelease,无需在进行release。


你可能感兴趣的:(内存管理,oc,自动释放池)