2010-05-30 51 views
2

我是Objective-C和iPhone開發的新手,已經使用Apress的Beginning iPhone 3 Programming作爲我幾個星期的主要指導。在少數情況下爲viewDidLoad中的一部分:方法,像breadTypes NSArray的實例變量被初始化像下面,具有限定的中間陣列,然後最終設置爲實際陣列是這樣的:正確的NSArray在方法中對伊娃數據進行初始化

NSArray *breadArray = [[NSArray alloc] initWithObjects:@"White", @"Whole Weat", @"Rye", @"Sourdough", @"Seven Grain", nil]; 
self.breadTypes = breadArray; 
[breadArray release]; 

爲什麼這樣做而不僅僅是這樣:

self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @"Whole Weat", @"Rye", @"Sourdough", @"Seven Grain", nil]; 

這兩個似乎工作時,我編譯和運行它。上面的第二種方法是否沒有做適當的內存管理?我假定initWithObjects:返回一個數組爲1的保留計數和餘最終在的dealloc再次釋放breadTypes:方法,以便很好地包裹東西:

- (void)dealloc { 
    ... 
    [breadTypes release]; 
    [super dealloc]; 
} 

設定器可通過標準的屬性定義(和最終的合成)指令:

@property (nonatomic, retain) NSArray *breadTypes; 

回答

4

第二種方式確實可能導致內存泄漏;你明確地創建一個數組(取得所有權),但是你沒有釋放它。

混合創建和分配的最佳方式是使用類構造函數(請參見NSArray參考)。當調用類的構造函數,你不把對象的所有權,所以有內存泄漏:

self.breadTypes = [NSArray arrayWithObjects:@"White", @"Whole Weat", @"Rye", @"Sourdough", @"Seven Grain", nil]; 
+0

最終,雖然在此ViewController的dealloc方法中,breadTypes數組並沒有被釋放。那裏有一個[breadTypes發佈]的電話。這不足以清理嗎? 我在猜測arrayWithObjects使用autorelease,並且這裏的想法可能是由於iPhone上的內存限制而對某些東西被釋放時有更嚴格的控制。 – 2010-05-30 09:59:47

+0

在你的第二種方式中,有一個缺失版本: 1)數組的創建給出了一個保留。 2)賦值給予保留。3)控制器的dealloc發佈。 你可以做什麼來調用發佈權後,賦予正確的發佈計數。但它取決於getter的實現。 – 2010-05-30 10:05:48

+0

洛朗,我想我現在明白了。查看我更新的帖子,瞭解設置setter的屬性定義。那麼在一行中,arrayWithObjects和setter方法都會將保留計數每增加1?那麼你是對的,在dealloc中調用release一次並沒有正確地清理它。謝謝! – 2010-05-30 10:15:08

0

在你的第二個版本,有內存泄漏。 breadTypes永遠不會被釋放。

既可以使用版本勞倫埃蒂安布勒建議:

self.breadTypes = [NSArray arrayWithObjects:@"White", @"Whole Weat", nil]; 

(許多類提供這樣的便利構造(這意味着所有的+ classWithSomething:

在不具有這樣的構造的情況下,你可以使用alloc,init,autorelease技術:

self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", nil] autorelease]; 

當然這會使用更多內存和一些CPU時間,但對於大多數應用程序而言,這並不重要,您不能忘記包含內存泄漏最常見原因的[obj版本]

我相信雖然蘋果建議不要在iPhone上使用autorelease ,但正如我所說的,在大多數情況下,這並不重要。

+0

如果您看Apple編程示例,則始終使用第一個版本。它具有「教育價值」實例化,設置伊娃,釋放。如你所示,另一個版本有引入泄漏的可能性。 在上面的例子中,結果是最小的,但是如果你使用autorelease在一個循環中實例化許多對象,它們將「閒逛」,直到自動釋放池被耗盡,即使它們可能不需要。 在內存有限的設備上,我儘量避免自動釋放,可能很難預測運行循環的運行距離。 Autorelease主要用於返回值,在我的書中。 – RickiG 2010-05-30 10:41:33

相關問題