2010-09-03 71 views
0

我已經設法讓自己對內存管理的某些元素感到困惑。我對於Objective-C和內存管理語言一般都陌生。iOS內存管理:ivars,靜態和NSStrings

我已閱讀內存管理指南,但我仍然對一些事情感到困惑。 1)是否需要清理ivars以及任何對象未保留的方法變量。例如

-(void) someMethod{ 
int count = 100; 
for (int i=0; i <count; i++) { 
    NSLog(@"Count = %d", i); 
} 
    }  

該方法完成後,「count」var會發生什麼變化? 如果一個方法分配了大量的臨時變量,那麼只要它們沒有未發佈,alloc'd對象,那麼這些變量是否會從內存中移除?或者我需要以某種方式將它們設置爲零? 2)如果我有一個靜態變量,例如一個NSString,當類被處理時,我是否必須做任何事情來從內存中移除它?

3)我注意到,NSString的保留計數似乎是2147483647,維基百科告訴我這是32位有符號整數的最大值。

http://en.wikipedia.org/wiki/2147483647

myString retainCount = 2147483647 

-(void) someMethod{ 
NSString *myString = @"testString"; 
NSLog(@"myString retainCount = %d", [myString retainCount]); 
// logs: myString retainCount = 2147483647 
} 

在方法結束時會發生這種什麼?這個記憶是否被清空了?該字符串不被任何東西引用。我的理解是,NSString的@「」方便方法返回一個自動釋放對象,但無論如何,使用retainCount來自動釋放某些東西的意義何在?在那種情況下,保留或釋放ANY NSString的意義何在?

我很清楚retainCount應該被忽略,但它只是讓我不知道這裏發生了什麼。

4)這是否有這個問題?我知道與NSString相關的內存沒有太多的可寫的地方,但我想成爲一名優秀的內存管理公民,而且我對最佳實踐更感興趣。

+3

實際上2147483647是* signed * 32位整數的最大值。它被Cocoa frammework用來表示一個不能被釋放的常量對象。您創建的普通NSStrings具有更多常規保留計數。 – JeremyP 2010-09-03 21:06:37

+0

感謝您的澄清。問題編輯相應。 – averydev 2010-09-03 21:38:14

回答

5

保留/釋放只對對象有效,而不是int,bool,float,double或其他內建。因此,將它用於id或其他持有指向對象的指針的類。在你的例子中,count不需要保留或釋放。它被分配在堆棧上,當函數返回時它會自動清理。

您確實需要處理任何本地對象alloc。這些都是使用設置爲1的retainCount創建的,因此您需要等待稍後或釋放它們。大多數Cocoa函數(不以copy或alloc開頭)返回一個自動釋放的對象。這意味着他們將在稍後發佈對他們的發佈 - 如果您對它們調用retain,則只能在該函數後面保留這些發佈。如果你希望清理它們,你不需要做任何事情(調用釋放會導致太多的釋放調用)。

如果您有一個靜態變量指向一個對象,那麼當該類的對象被處理時,它不會被觸摸。如果你想要它被釋放,你必須調用它釋放。如果靜態是一個int,bool或其他內置的,那麼你不能(不能)在它上面調用release。這是你的應用的全球記憶的一部分。

設置爲字符串文字的NSString不應該具有對其調用的版本。 retainCount對他們來說毫無意義。對於signed int值,該值也是-1。

如果你這樣做 - [[NSString alloc] initCallHere:etc] - 你必須調用它的釋放。大多數時候你得到字符串,你不使用alloc,所以你不需要調用release。如果你保留一個,你需要調用release。

是的,它確實很重要。隨着時間的推移,泄漏將導致iPhone殺死你的應用程序。

+0

感謝您的回答,那麼使用@「」語法創建的字符串會保留在內存中,直到應用程序被終止?還是將它們放入池中進行清理,除非進一步保留? – averydev 2010-09-03 21:34:42

+1

「@」「字符串實際上是靜態的 - 也就是說,應用程序的內存映像的一部分。你不需要清理它們(儘管它實際上並不重要,因爲實際上它們具有無限的保留計數)。如果使用這樣的字符串''alloc','copy'或'new'對象,那麼您應該'釋放'該對象。 – walkytalky 2010-09-03 21:41:13

+0

應用程序中@「」字符串的數量,例如大量日誌語句或其他短期使用情況是否會影響應用程序的性能或顯着增加其內存佔用量? 如果短期使用字符串變量,使用@「」創建時它們的用處已經過期了嗎? – averydev 2010-09-03 23:41:08

2
  1. 你不需要擔心count因爲它是一個整數,一個原始數據類型,而不是一個對象。

  2. 我讀過那些只是在應用程序終止或如果你明確釋放它們時纔會消失。

  3. 你是對的,你應該不是擔心這種方式的保留數。 Cocoa自動給予@""NSConstantString對象)絕對最高的保留值,以便它們不能被分配。

  4. 你已經過了複雜的主題。 三個準則的目的是讓你知道你只需要擔心在三種特定情況下的內存管理。 Apple爲您提供這些指導方針,以便不必擔心每個班級的具體內部情況(如手動跟蹤retainCount),更不用說有時Cocoa會以不同的方式做事(如NSConstantString)。只要你記住這些指導方針,你就不必知道底下發生的事情的細節(當然,對保留數概念的理解有幫助,但將其與手動跟蹤相比較)。

我不知道哪個引導你具體看,但如果你沒有給this one一試,我強烈推薦它。它以簡明和直接的方式總結了三條指導原則。

2

可可內存管理規則只覆蓋Objective C對象。

當任何子程序或方法退出時(實際上堆棧內存僅由相同線程中的後續子例程或方法重用/覆蓋),將清除局部變量(非靜態)。需要內存(字符串)和靜態變量的常量會在應用程序退出後被操作系統拆除時進行清理。手動釋放內存時,手動清除內存。

但是,您分配或保留的任何對象:(無論是分配給伊娃,本地,全局,靜態等)必須像其他任何對象一樣進行管理。除非您非常擅長保留計數管理,否則請小心將對象分配給全局變量。