Obj-c为每个对象提供一个内部计数器,负责跟踪对象的引用次数,引用次数的增减分别对应
NSObject的retain和release方法,当引用次数为0时,对象将会得到马上回收。
对象的创建
alloc和copy系列方法,都会发送一条retain消息,引用计数都会加1,
"是谁生的孩子,就应该谁来养"
重写dealloc方法
当对象包含其他对象时,就得在dealloc方法中释放他们
-(void) dealloc{
[myvar release];
.......
[super release];
}
内存自动释放池
Autorelease pool提供了一个对象容器,当对象发送autorelease消息时,对象的引用计数并不减少,内存自动释放池会添加一条相应的记录,记录下对象的这种要求,当内存自动释放池发送release消息时,会通知池中的所有对象去发送release消息,引用计数才会真正减少
模板代码
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[myobject autorelease];
......
[pool release];
属性的内存管理
设置属性和构造方法中初始化成员变量的值时很容易引发内存泄露
//错误的写法
-(void) setTitle:(NSString*) newTitle{
//旧的title的内存并没有得到释放
//并且这样只是对指针的赋值,很容易引发问题
title = newTitle;
}
//正确的写法(相当于属性参数中的retain参数)
-(void) setTitle:(NSString*) newTitle{
//确保传进来的newTitle不会被release
[newTitle retain];
//释放旧的title
[title release];
//创建一个新的title
title = [[NSString alloc] initWithString:newTitle];
[newTitle release];
}
//正确的写法(相当于属性参数中的copy参数)
-(void) setTitle:(NSString*) newTitle{
//确保传进来的newTitle不会被release
[newTitle copy];//只对实现了NSCopying协议的对象成立
//释放旧的title
[title release];
//创建一个新的title
title = [[NSString alloc] initWithString:newTitle];
[newTitle release];
}
assign参数适用于基本类型直接赋值
-(void) setAge:(int) newAge{
age = newAge;
}
构造方法内存管理写法
-(id) initWithTitle:(NSString*) newTitle{
self = [super init];
if(self){
[self setTitle:newTitle];
//这种写法会发生内存泄露和指针问题,是错误的写法
//self->title = newTitle;
}
}