标签:
在进行内存管理的时候要注意内存管理的准则:谁开辟内存,谁释放内存(谁污染的谁治理) 。
开辟内存之后,对象的引用计数为1,只有继承自NSObject的对象才有内促管理的概念, 当对象引用计数为0的时候对象的内存会被清理。
Person *p = [[Person alloc] init];
//指针赋值并不会让对象的引用计数器+1
Person *p2 = p ;
// 输出p2 retainCount = 1, p retainCount = 1
NSLog(@"p2 retainCount = %lu , p retainCount = %lu",[p2 retainCount],[p retainCount]) ;
// retain 会让引用计数器+1
Person *p3 = [p retain] ;
// 输出2,2,2
NSLog(@"p3 retainCount = %lu,p2 retainCount = %lu , p retainCount = %lu",[p3 retainCount],[p2 retainCount],[p retainCount]) ;
// 释放对象,谁污染的谁治理
[p release] ; // 引用数量变为1
// 释放对象
[p3 release] ; // 引用数量变为0 , 调用对象dealloc方法
//[p2 release] ; // 这句报错,因为所指向的对象已经被释放掉了
在开发过程中,某些对象可能并不能立马释放掉,可以暂时将这个对象托管进当前上下文中的自动释放池,以便最后统一释放。
// 创建自动释放池
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Person * p = [[Person alloc] init];
// 添加到自动释放池
[p autorelease] ;
// 自动释放,其中托管的对象也会被释放
[pool release] ;
@autoreleasepool {} 是NSAutoreleasePool 的另一种写法,‘{}‘ 内的代码就是在一个NSAutoreleasePool 中。
@autoreleasepool{
} // 相当于系统自动创建NSAutoreleasePool 自动在结尾处让这个pool release.
程序中可以嵌套多个自动释放池,autorelease 的对象托管在对象代码所在的释放池。
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
Person *p1 = [Person new];
// 被托管在pool1 中
[p1 autorelease] ;
NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
Person *p2 = [Person new];
// 被托管 在 pool2中
[p2 autorelease];
[pool2 release] ;
[pool1 release] ;
在开发IOS程序的时候,处理一个按钮的单击事件会调用单击响应的方法,系统会创建一个新的自动释放池给这个响应方法使用,当这个事件处理方法结束后系统就会release创建的自动释放池,由于事件可以多次循环发生,每一次发生系统都会创建一个针对于当前事件的自动释放池,事件处理完毕后释放这个自动释放池。我们可以使用retain来保存对象不被事件自动创建的自动释放池清理.
系统API中的对象大多是被自动释放池托管的,所以我们无需关心这些对象的释放。
-(void) onClick {
// 在事件方法结束后data 所指向的内存块默认会被清理,为了保留下来data 对象,我们使用了retain关键字.
data = [[NSMutableArray array] retain] ;
}
当一个累的属性是另一个对象的指针时,我们可以重写dealloc方法来释放属性对象。
@implementation Person
{
// 是指针 , 存在于内存中。
NSObject *obj ;
}
// 重写父类的dealloc 方法
- (void)dealloc
{
NSLog(@"test") ;
// 释放属性
[obj release] ;
// 注意:必须写上这一句,释放父类的资源
[super dealloc] ;
}
@end
// 引入Person 类
#import "Person.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Person *p = [Person new] ;
// p release 的时候会调用dealloc 方法,释放Person类自身的属性.
[p release] ;
}
return 0;
}
@property(assign) NSObject *obj ;
retain 属性合成的setter 保留一下再赋值,引用计数器+1
-(void)setObjA:(ClassA *)a
{
If(objA != a)
{
[objA release];
objA = [a retain];//对象的retain count 加1
}
}
assign 属性合成的setter直接赋值,引用计数器不会+1
-(void)setObjA:(ClassA *)a
{
objA = a;
}
标签:
原文地址:http://www.cnblogs.com/mrwu/p/4331161.html