2011-10-25 89 views
1

我經常看到這樣的:而不是爲什麼要製作臨時對象,將它們設置爲變量,然後釋放它們?

NSArray *tmpArr = [[NSArray alloc] initWithObjects:@"Info", nil]; 
self.userInfo = tmpArr; 
[tmpArr release]; 

self.userInfo = [[NSArray alloc] initWithObjects:@"Info", nil]; 

有誰知道爲什麼上面的代碼示例是更受歡迎?內存管理比第二個更正確嗎?

+0

完全相同的副本(http://stackoverflow.com/questions/7017046/objective-c-newbie-question-about -allocation-保留和釋放) –

回答

5

由於數組未被釋放,第二個代碼片段導致內存泄漏。在大多數情況下,對象類型的屬性(在本例中爲NSArray)屬於retaincopy屬性,這意味着它們可以增加指定值的引用計數或複製整個對象。然後局部變量可以(並且應該)被釋放,如果它不再需要的話。

非泄漏替代剪斷第二代碼將使用autorelease

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease]; 

或簡單地:

self.userInfo = [NSArray arrayWithObjects:@"Info", nil]; 
2

假設屬性userInfo標記retain,第二形式將泄漏存儲器。 [[NSArray alloc] initWithObjects]將創建一個引用計數爲1的數組。將它分配給retain屬性會將引用計數增加到2,並且它永遠不會回到零並被釋放。它可以固定或者通過使用你所列出的第一種形式或方式:

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease]; 

以便自動釋放將遞減引用計數,一個在運行循環的下一次迭代。從那時起,當userInfo被清除時,引用計數將降至零,並且該數組將被銷燬。

你也應該看看其他任何原因,這question

2

除了有可能是,它使代碼更易讀,並有助於防止錯誤。

您的兩個示例並不等同,因爲您忘記在第二個示例中釋放新的alloc/init'ed數組。您將需要

self.userInfo = [[[NSArray alloc] initWithObjects:@"Info", nil] autorelease]; 

這裏。

QED第一個原因;-P

而且,當你第一次創建一個局部變量,你可以通過屬性宣傳他們之前建立更復雜的對象。例如,如果你在這裏使用了一個可變的數組,並且填充了一些更復雜的邏輯,將其分配給屬性,並且只有在填充它時,類的客戶端纔可以訪問屬性及其內容只有一半準備好 - 這是一個零星的,很難重現錯誤的好規定。

因此,即使在您的情況下,使用本地變量也不一定是嚴格必要的(如果您有autorelease'd我們會使用新的自動參考Couting「ARC」,它可以自動解決泄漏問題),在我看來,首先是一個好主意讓一切準備就緒,然後使它可見。

清潔代碼規則:)

目的C:關於分配新手問題,保留和釋放]的
相關問題