标签:
在进行内存管理的时候要注意内存管理的准则:谁开辟内存,谁释放内存(谁污染的谁治理) 。
开辟内存之后,对象的引用计数为1,只有继承自NSObject的对象才有内促管理的概念, 当对象引用计数为0的时候对象的内存会被清理。
Person *p = [[Person alloc] init];//指针赋值并不会让对象的引用计数器+1Person *p2 = p ;// 输出p2 retainCount = 1, p retainCount = 1NSLog(@"p2 retainCount = %lu , p retainCount = %lu",[p2 retainCount],[p retainCount]) ;// retain 会让引用计数器+1Person *p3 = [p retain] ;// 输出2,2,2NSLog(@"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