2009-08-16 46 views
2

據我所知,第一個完成後你必須釋放,第二個你不需要釋放。爲什麼你會在第二次初始化時使用?這兩個init方法有什麼區別?

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"title", @"text", nil]; 

而且

NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"title", @"text", nil]; 

回答

2

正如其他人所說,從某種意義上說,你的兩個例子沒有區別,只是第一個例子返回一個保留的對象,直到你明確釋放它纔會被釋放,而第二個是自動釋放對象將在下一次運行循環開始時自動釋放,除非在此之前明確保留它。

然而,關鍵的部分,你的問題是:

你爲什麼要使用第一 初始化在第二?

常用認爲方法(支持蘋果文檔)是使用自動釋放的對象是在大多數情況下,精絕。我不同意彼得劉易斯在這裏關於iPhone是如此「動力不足」,你需要避免自動釋放對象。在大多數應用程序中提供自動釋放對象的手機上的額外開銷是微乎其微的。因此,可以隨意在代碼中使用自動釋放對象,並且只要明確地保留它們就可以保留它們。

但是,它在哪裏確實有所作爲緊圈。如果您正在運行一個執行1000次的while循環,並且您正在該循環內創建後續不需要的對象,則應明確創建新的非自動釋放對象並明確釋放它們。這是因爲autorelease池在緊密循環內不會(默認情況下)爲空。創建大量自動釋放對象很可能會開始影響設備內存的限制。

所以總之;使用2)大部分時間,但使用1)如果你打算一次創建和拋棄很多對象。

希望可以幫到

+2

+ +1提到緊密循環的特殊野獸。我想補充一點,如果你在一個使用自動釋放對象的緊密循環中使用了很多庫調用,你可以爲循環的每次迭代創建和銷燬一個NSAutoreleasePool。這並不昂貴,並且可以阻止可能令人討厭的內存膨脹。 – 2009-08-17 12:40:07

+0

是香椿上的點。我確實想到提到這一點,但決定我的帖子足夠長了! – h4xxr 2009-08-17 15:31:33

0

第一init方法是instance法(適用於由[NSMutableDictionary alloc]返回的實例),而不是一個autoreleased對象,具有1

一個保留計數第二個方法是class方法,並返回一個自動釋放對象(基本上沒有保留計數)。

2

你是對的;在第一個版本中,您需要明確釋放該對象。如果您將其分配給類中的實例變量,那麼第一個版本非常有用;即它是一個超出當前UI事件生活的字典(後一個對象是自動發佈的,並且以後在你的程序中不可用)。

例如:

-(id)init 
{ 
    if (self = [super init]) 
    { 
     myDict = [[NSDictionary alloc] init ...]; 
    } 
    return self; 
} 

-(void)dealloc 
{ 
    [myDict release]; 
    [super dealloc]; 
} 
0

第二個是由其中的第一個,你處理你自己的內存管理的NSMutableDictionary類發佈汽車。

0

閱讀memory management rules。 9段短文,你可以在大約一分鐘內閱讀。他們清楚地解釋了兩者之間的差異。

至於爲什麼你應該使用一個或另一個,它取決於平臺。

在iPhone上,由於電量不足和內存不足,您通常會更喜歡前者,除非您將被迫使用autorelease(例如,如果您要從名稱爲的方法返回它不以「alloc」或「new」開始或包含「copy」)。如果你要autorelease它,然後使用第二種形式。否則,請使用第一個表單並在方法中明確地釋放它。

在Mac上,它具有足夠的功能和內存來使autorelease池成爲一個簡單的細節(除了最困難的情況外),您可以在任何情況下使用第二種形式。通常情況下,如果你要保留它,你會將它分配給一個複製/保留屬性,所以你不需要保留它。例外情況是在init方法中,你不能使用setter,或者在手動執行的setter中,因此需要自己分配給ivar。在這些情況下,你會經常使用前者。

但是,所有這些只是風格/過早優化(在這種情況下不一定是壞的,因爲in是一種低級別的噪音優化,分析不會檢測到,並且通常會減慢應用程序的速度) 。重要的是閱讀規則並遵循他們的說法,如果你這樣做,你可以隨意使用任何一種形式。