0

我遇到了一個在autorelease池中似乎被稱爲「溺水」的問題。自動釋放溺水

我的代碼正確地創建和銷燬對象。但是,我使用一些類方法,在我不知道它的情況下自動釋放幾個變量。考慮到他們每分鐘循環成千上萬次......我發現自己淹沒了程序中某處失去的數千個未發佈的對象。

2個問題:

  1. 因此,無論我不使用類的方法在所有 - 是一個永久性的解決方案,或者,即便如此,將一些實例方法(基金會,UIKit的)還是自動釋放對象沒有我瞭解它?

  2. 或者我可以在調用類方法之前分配一個自動釋放池,並在調用類方法之後將其排空 - 這是一個永久的解決方案嗎?

回答

2
  1. 僅僅因爲你不使用一個類的方法,並不意味着你要避免自動釋放的對象。例如:NSString * path = [anotherString stringByAppendingPathComponent:@"foo"]返回一個自動釋放對象,但沒有涉及任何類方法。據我所知,避免自動釋放對象的唯一方法是不使用對象。如果你真的想要去那條路線,檢查CoreFoundation。 (我不建議走這樣一條路。)

  2. 如果你有一個創建噸的自動釋放池的一些瘋狂的工廠方法,那麼我可能會做這樣的事情:

    + (id) crazyFactoryMethodWithFoo:(id)foo { 
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
        id returnValue = nil; 
        //generate gobs of autoreleased objects 
        returnValue = [something retain]; 
        [pool release]; 
        return [returnValue autorelease]; 
    }

    通過明確保留在清除池之前的返回值,您確保返回值超出了autorelease池的銷燬。然後通過自動釋放返回值並返回它來平衡retain

+0

@Dave DeLong很好。問題是我始終使用NSUserDefaults ...並且此類的方法創建自動釋放對象。現在我明白爲什麼蘋果不推薦它。我也一直使用NSString方法,就像你提到的那樣。而循環,我得到這些奇怪的問題。你有什麼建議用簡單的方法替換NSUserDefaults?謝謝。 – GSchv 2010-08-14 22:40:55

+0

@GSchv爲什麼你認爲你需要更換'NSUserDefaults'?如果它返回一個自動釋放對象,並且想要在當前自動釋放池的生命週期之後掛在那個對象上,那麼只需「保留」該對象(然後在完成時釋放它)。 – 2010-08-14 22:43:05

+0

'[pool drain]'是首選方法http://developer.apple.com/mac/library/documentation/cocoa/reference/foundation/Classes/NSAutoreleasePool_Class/Reference/Reference。html#// apple_ref/occ/instm/NSAutoreleasePool/release – cobbal 2010-08-15 00:50:26

2

Dave DeLong已經回答了您的問題,但通常只有當您將池填滿太高時,纔會處於非常緊密的環路中。在這種情況下,只需爲循環的每次迭代創建另一個自動釋放池。

for (NSUInteger i = 0; i < 1000000000; i++) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    // do the work 

    [pool release]; 
} 

對象會自動添加到當前線程的最近創建的自動釋放池中。通過爲循環的每次迭代創建一個,可以快速清除不需要的對象,而不是讓它們堆積在運行循環的池中。

+0

這似乎是唯一的選擇。謝謝。 – GSchv 2010-08-15 01:42:50