天天看點

NSAutoReleasePool使用中drain和release的差別

雖然ARC引入之後NSAutoReleasePool的使用有了很大變化,但是了解NSAutoReleasePool的機制還是十分必要的,下面主要說一下:

NSAutoReleasePool * pool = [NSAutoReleasePool alloc] init];

//do something

之後,

[pool drain] 和 [pool release] 的差別:

release,在引用計數環境下,由于NSAutoReleasePool是一個不可以被retain的類型,是以release會直接dealloc pool對象。當pool被dealloc的時候,pool向所有在pool中的對象發出一個release的消息,如果一個對象在這個pool中autorelease了多次,pool對這個對象的每一次autorelease都會release。在GC環境下release是一個no-op操作(代表沒有操作,是一個占據進行很少的空間但是指出沒有操作的計算機指令)。

drain,在引用計數環境下,它的行為和release是一樣的。在GC的環境下,這個方法調用objc_collect_if_needed出發GC。

是以,重點是:在GC環境下,release是一個no-op,是以除非你不希望在GC環境下出發GC,你都應該使用drain而不是使用release來釋放pool。

1. NSAutoreleasePool實際上是個對象引用計數自動處理器。NSAutoreleasePool可以同時有多個,它的組織是個棧,總是存在一個棧頂pool,也就是目前pool,每建立一個pool,就往棧裡壓一個,改變目前pool為建立的pool,然後,每次給pool發送drain消息,就彈出棧頂的pool,改目前pool為棧裡的下一個 pool。

2. 在程式的入口main函數就調用NSAutoreleasePool,這樣保證程式中不調用NSAutoreleasePool,但在退出時自動釋放。新開線程最好實作NSAutoreleasePool

3. NSAutoreleasePool的管理範圍是在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];與[pool release];之間的對象

4. NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; 

當執行[pool autorelease]的時候,系統回進行一次記憶體釋放,把autorelease的對象釋放掉,如果沒有NSAutoreleasePool , 那這些記憶體不會釋放

注意,對象并不是自動被加入到目前pool中,而是需要對對象發送autorelease消息,這樣,對象就被加到目前pool的管理裡了。當目前pool接受到drain消息時,它就簡單的對它所管理的所有對象發送release消息。

例如

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* nsstring;

char* cstring = "Hello CString";

nsstring = [NSString stringWithUTF8String:cstring];

[pool release];

5. alloc的對象必須顯示釋放

例如:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* string = [[NSString alloc] init];

[string stringByAppendingString:@"Hello World!"];

[pool release];

[nsstring release];