自动释放池
自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来统一回收释放。当自动释放池销毁的时候,池子里面的所有对象都进行release操作。
任何OC对象只要调用autorelease方法,就会把该对象放到离自己最近的释放池中(栈顶的释放池)。
创建自动释放池
@autoreleasepool
{ //自动释放池创建
…. //花括号中的临时变量在花括号结束后就会被销毁
} //自动释放池释放
Dog.h
#import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property int ID; + (id ) dog; @end
Dog.m
#import "Dog.h" @implementation Dog @synthesize ID = _ID; -(void) dealloc { NSLog(@"Dog %d id dealloc.",_ID); [super dealloc]; } + (id) dog { Dog * d = [[[Dog alloc] init] autorelease]; return d; //以上两句也可以这么写return [[[Dog alloc] init] autorelease]; /*不可以在这个函数中创建一个自动释放池,然后将对象放入自动释放池,最后在释放自动释放池 */ } @end
Person.h
#import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } @property (retain) Dog *Dog; @end
Person.m
#import "Person.h" @implementation Person @synthesize Dog = _dog; -(void) dealloc { self.Dog =nil; NSLog(@"Person is dealloc."); [super dealloc]; } @end
mian.m
#import <Foundation/Foundation.h> #import "Dog.h" #import "Person.h" int main () { @autoreleasepool {
Person *xiaoli = [[Person alloc]init]; Dog *dog1 = [[Dog alloc] init] ;//此时dog1为弱引用 // Dog *dog1 = [Dog dog];//以后就不能使用[dog1 release];,否则,不符合黄金法则 //Dog *dog2 = dog1;//此时dog2为弱引用,因为次对象并没有对retainCount进行加1 NSLog(@"dog retaincount is %ld",[dog1 retainCount]); xiaoli.Dog = dog1; NSLog(@"dog retaincount2 is %ld",[dog1 retainCount]); //[dog1 release]; [xiaoli release]; NSLog(@"dog retaincount3 is %ld",[dog1 retainCount]); [dog1 release]; } return 0; }
注意要使以上的代码测试成功,需要将Build Settings中的Automatic Reference Counting设置为NO,才能运行成功。
自动释放变量一般用到的地方:
一般OC的构造函数都提供类的构造函数和对象的构造函数,类的构造函数都是autorelease的。
OC中所有类都提供了两种构造函数,一种是以init开头的构造函数,一种是以类名字开头的构造函数,例如:
以init开头的例子:
NSNumber *zero_a = [[NSNumber alloc] initWithFloat:0.0];
……
[zero_a release];
以类名字开头的例子:
NSNumber *zero_b = [NSNumber numberWithFloat:0.0];//使用autorelease延迟释放内存
//绝不能[zero_b release];
自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来统一回收释放。当自动释放池销毁的时候,池子里面的所有对象都进行release操作。
任何OC对象只要调用autorelease方法,就会把该对象放到离自己最近的释放池中(栈顶的释放池)。
创建自动释放池
@autoreleasepool
{ //自动释放池创建
…. //花括号中的临时变量在花括号结束后就会被销毁
} //自动释放池释放
Dog.h
#import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property int ID; + (id ) dog; @end
Dog.m
#import "Dog.h" @implementation Dog @synthesize ID = _ID; -(void) dealloc { NSLog(@"Dog %d id dealloc.",_ID); [super dealloc]; } + (id) dog { Dog * d = [[[Dog alloc] init] autorelease]; return d; //以上两句也可以这么写return [[[Dog alloc] init] autorelease]; /*不可以在这个函数中创建一个自动释放池,然后将对象放入自动释放池,最后在释放自动释放池 */ } @end
Person.h
#import <Foundation/Foundation.h> #import "Dog.h" @interface Person : NSObject { Dog *_dog; } @property (retain) Dog *Dog; @end
Person.m
#import "Person.h" @implementation Person @synthesize Dog = _dog; -(void) dealloc { self.Dog =nil; NSLog(@"Person is dealloc."); [super dealloc]; } @end
mian.m
#import <Foundation/Foundation.h> #import "Dog.h" #import "Person.h" int main () { @autoreleasepool {
Person *xiaoli = [[Person alloc]init]; Dog *dog1 = [[Dog alloc] init] ;//此时dog1为弱引用 // Dog *dog1 = [Dog dog];//以后就不能使用[dog1 release];,否则,不符合黄金法则 //Dog *dog2 = dog1;//此时dog2为弱引用,因为次对象并没有对retainCount进行加1 NSLog(@"dog retaincount is %ld",[dog1 retainCount]); xiaoli.Dog = dog1; NSLog(@"dog retaincount2 is %ld",[dog1 retainCount]); //[dog1 release]; [xiaoli release]; NSLog(@"dog retaincount3 is %ld",[dog1 retainCount]); [dog1 release]; } return 0; }
注意要使以上的代码测试成功,需要将Build Settings中的Automatic Reference Counting设置为NO,才能运行成功。
自动释放变量一般用到的地方:
一般OC的构造函数都提供类的构造函数和对象的构造函数,类的构造函数都是autorelease的。
OC中所有类都提供了两种构造函数,一种是以init开头的构造函数,一种是以类名字开头的构造函数,例如:
以init开头的例子:
NSNumber *zero_a = [[NSNumber alloc] initWithFloat:0.0];
……
[zero_a release];
以类名字开头的例子:
NSNumber *zero_b = [NSNumber numberWithFloat:0.0];//使用autorelease延迟释放内存
//绝不能[zero_b release];