2011-11-16 63 views
2

在Objective-C手動上所記的東西像誰擁有autorelease對象?

return [[[SomeClass alloc] init] autorelease]; 

可以完成,然後release沒有必要在任何時候,甚至在接收到該對象的功能。誰擁有這個對象呢?它何時會被釋放?

回答

7

當前NSAutoreleasePool確實會在排水時處理釋放。

IBAction調用被包裝成NSAutoreleasePool,在調用之後被調用。

對於所有非IBAction爲調用以下將適用:

說,你有這些方法:

- (id)foo { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    SomeClass *bar = [self bar]; //bar still exists here 
    //do other stuff 
    //bar still exists here 
    //do other stuff 
    //bar still exists here 
    [pool drain]; //bar gets released right here! 
    //bar has been released 
} 

- (id)bar { 
    return [[[SomeClass alloc] init] autorelease]; //bar will still be around after the return 
} 

考慮另一種情形:

- (void)foo { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    //do other stuff 
    [self bar]; 
    //do other stuff 
    [pool drain]; //the string from blee would be released right here; 
} 

- (void)bar { 
    [self baz]; 
} 

- (void)baz { 
    NSString *string = [self blee]; 
} 

- (id)blee { 
    return [NSString string]; //autoreleased 
} 

正如你可以看到自動釋放字符串對象甚至不必用於或返回到創建池的範圍。

NSAutoreleasePools堆棧(每線程)上存在和自動釋放對象獲得通過的最頂層,在調用autorelease時間的池擁有。


更新: 如果你正在處理一個緊密循環,並希望保持內存適度低,而不會減慢您的循環,可考慮做這樣的事情:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
for (NSUInteger i = 0; i < 1000000000; i++) { 
    [NSString stringWithString:@"foo"]; 
    if (i % 1000 == 0) { 
     [pool drain]; 
     pool = [[NSAutoreleasePool alloc] init]; 
    } 
} 
[pool drain]; 

然而NSAutoreleasePool高度優化,所以每次迭代一個池通常不是一個問題。


要充分了解如何NSAutoreleasePools做工閱讀本excellent article by Mike Ash

+0

當它倒掉? – Dani

+0

如果你明確地創建了它,當你調用[pool drain](最佳實踐)時,或者池本身被釋放時[pool release],它會被耗盡。如果你使用的隱式autorelease池,它由運行循環管理,原則上每次都會被清空。 – isaac

+0

@Dani:延長我的回答。現在應該更清楚了。 – Regexident