NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
[pool drain]:这个函数可以把autoreleasePool里的对象释放
在for循环中每次都释放内存池的示例:
NSAutoreleasePool *tempPool;
…
for(i = 0; i<n;++i)
{
tempPool= [[NSAutoReleasePool alloc] init];
…//lots of work with temporary objects here
[tempPool drain];
}
autoreleasePool保存了实际对象的引用,当调用drain函数的时候将其释放
将一个对象放入autoreleasePool中:[myFraction autorelease];
每次调用retain方法,对象的引用计数就会加1
[myFraction retain]
当一个对象被加入数组里,它的引用计数也会加1
当调用一次release函数后,该对象的引用计数会减1
[myFraction release]
当一个对象引用计数为0的时候,系统就会调用该对象的dealloc消息将其所占用的内存释放掉
当调用一个对象的retainCount消息时候,该消息会返回一个NSUInteger类型的正整数,这个数字代表当前该对象的引用计数。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// insert code here...
NSNumber *myInt = [[NSNumber alloc] initWithInteger:100];
NSNumber *myInt2;
NSMutableArray *myArr = [NSMutableArray array];
NSLog(@"myInt retain count = %lx",(unsigned long)[myInt retainCount]);
[myArr addObject:myInt];
NSLog(@"after adding to array = %lx",(unsigned long)[myInt retainCount]);
myInt2 = myInt;
NSLog(@"after asssignment to myInt2 = %lx",(unsigned long)[myInt retainCount]);
[myInt retain];
NSLog(@"myInt after retain = %lx",(unsigned long)[myInt retainCount]);
NSLog(@"myInt2 after retain = %lx",(unsigned long)[myInt2 retainCount]);
[myInt release];
NSLog(@"after release = %lx",(unsigned long)[myInt retainCount]);
[myArr removeObjectAtIndex:0];
NSLog(@"after removal from array = %lx",(unsigned long)[myInt retainCount]);
[myInt2 release];
[pool drain];
return 0;
}
结果:
myInt retain count = 1
after adding to array = 2after asssignment to myInt2 = 2myInt after retain = 3
myInt2 after retain = 3
after release = 2
after removal from array = 1
myInt = [myArr ObejctAtIndex:0]
...
[myArr removeObjectAtIndex:0]
当数组移除对象后,myInt所指向的对象可能已经被回收,代码可能会崩溃
所以myInt在获得数组对象的时候,还需要调用一次retain
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
NSString *myStr1 = @"Constant string";
NSString *myStr2 = [NSString stringWithString:@"string 2"];
NSMutableString *myStr3 = [NSMutableString stringWithString:@"string 3"];
NSMutableArray *myArr = [NSMutableArray array];
NSLog(@"Retain count:myStr1: %lx,myStr2:%lx,myStr3:%lx",(unsigned long)[myStr1 retainCount],(unsigned long)[myStr2 retainCount],(unsigned long)[myStr3 retainCount]);
[myArr addObject:myStr1];
[myArr addObject:myStr2];
[myArr addObject:myStr3];
NSLog(@"Retain count:myStr1: %lx,myStr2:%lx,myStr3:%lx",(unsigned long)[myStr1 retainCount],(unsigned long)[myStr2 retainCount],(unsigned long)[myStr3 retainCount]);
[myStr1 retain];
[myStr2 retain];
[myStr3 retain];
NSLog(@"Retain count:myStr1: %lx,myStr2:%lx,myStr3:%lx",(unsigned long)[myStr1 retainCount],(unsigned long)[myStr2 retainCount],(unsigned long)[myStr3 retainCount]);
// Bring the reference count of myStr3 back down
[myStr3 release];
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
结果:
Retain count: myStr1: fffffffffffffff, myStr2: fffffffffffffff, myStr3: 1Retain count: myStr1: fffffffffffffff, myStr2: fffffffffffffff, myStr3: 2Retain count: myStr1: fffffffffffffff, myStr2: fffffffffffffff, myStr3: 3
当对一个对象调用retain消息的时候,在不用该对象的时候一定要记得调用其的release方法。通过copy,mutableCopy,alloc,new获得的对象也需要在使用结束后调用release方法
在ios程序中,一个事件循环会新建一个新的AutoreleasePool,并把之前的给drain掉,所以在这期间,任何没有retain的内存池对象都会被销毁。