2012-02-26 76 views
0

我正在學習objectiveig和編程一個iPad應用程序。內存管理是我不斷重複並不得不重新閱讀的一件事。我到達那裏......慢慢地。基本規則如每alloc/retain你必須有release是有用的。然而,一個比較基本的東西躲開我,我不知道是否有人能解釋...瞭解ios中的內存管理

看看下面的代碼...

NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

這是相對簡單的編碼,並且將需要[myArray release]聲明。

不過,我一直看到的例子(實際上,我已經廣泛以下「捷徑」用...

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

如何,據我瞭解,當你使用你不要的(NSString *)需要使用[myArray release]聲明,但我不明白爲什麼。

可能有人可能解釋?

回答

1

在第一行:

NSArray *myArray = [[NSArray alloc] init] 

一定數量的內存分配給一個數組(實際上在這種情況下,它是毫無意義的,因爲數組的大小爲0。請記住,NSArray中是不變的! )。 變量myArray保存保留內存區域的第一個字節的地址。

現在在第二行中,您將更改myArray的值,該值現在將指向存儲[someNSSet allObjects]的內存區域的第一個字節。在這一刻,你不知道數組的存儲位置是在第一行創建的。所以你有泄漏。

行:

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

是正確的,因爲你沒有在這一點上預留的內存。如果您不使用ARC,則可能會調用retain以使GC遠離引用的內存塊。換句話說,當對象的所有者釋放它並嘗試訪問它時,您可能會收到BAD_EXEC例如:[myArray objectAtIndex:0]

2
NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

此代碼泄漏myArray,因爲您失去了在第一行分配的NSArray的引用;這裏您不需要alloc,因爲在第二行中,您將爲myArray分配一個新值。

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

與此代碼示例是完全沒有問題,你分配的[someNSSet allObjects]myArray指針的結果,你沒有自己的返回值,所以你不必在意釋放它。

考慮爲您的項目使用ARC(自動保留計數)。使用ARC,編譯器負責保留計數,因此您不必實際不允許這樣做。有一個重構將轉換當前的項目。

+0

爲什麼我不擁有返回的值。誰/什麼? – 2012-02-26 18:35:29

+0

@BenThompson:當你創建一個對象(new或alloc,copy或mutableCopy)時,它的保留計數爲1,並且你擁有它。 當你發送一個對象一個保留消息時,它的保留計數增加1,你也擁有它。您只需要釋放您擁有的對象。 – 2012-02-26 18:39:28

+1

@Ben:最有可能的是autorelease池是從'allObjects'返回的對象的所有者。另一種可能性是set對象,但這隻會在集合暴露一個已經擁有的對象時纔會發生,而不是創建一個新的數組。但是,除了瞭解背景中發生的事情外,你不應該關心誰擁有事物。無論你做或不做,這都是你需要考慮的。 – 2012-02-26 18:48:55

2

正如您所說,您發佈的第一個代碼有泄漏。所以你必須添加一個版本:

NSArray *myArray = [[NSArray alloc] init]; 
[myArray release]; 
myArray = [someNSSet allObjects]; 

事實上,當你獲得通過,與allocnewcopy,你擁有它開始的方法的對象,你應該釋放它。這就是爲什麼,在這裏你應該釋放你使用方法alloc獲得的數組。這個約定可以很容易地知道你何時擁有對象,什麼時候不擁有對象。所以請記住:alloc,newcopy

至於第二實施例,則得到的數組雖然不與這三個詞(allocnewcopy)中的一個啓動的方法,這樣就不會擁有該對象,而你不負責釋放它。實際上,您獲得的數組是一個自動釋放對象,這意味着即使其保留計數當前爲1,當被稱爲autorelease池的內容被耗盡時,它也會自動釋放。

以下是關於Memory Management Rules的參考。

+0

可能會更好地在你的答案代碼中使用第3行倒行第2行(或者使用autorelease而不是發行版) – meronix 2012-02-26 19:39:13

+0

第2行中的'release'是爲了平衡第2行中的'alloc',以便'myArray'的舊值不泄漏。在爲myArray分配一個新值之前,我們需要做到這一點。 – sch 2012-02-26 19:44:37

+0

是的,當然,但如果你釋放它,在第3行myArray不再存在,它沒有更多的分配,可能會給你錯誤,你不能使用它。你必須平衡alloc和release,並在這兩行之間使用你的對象。或不? – meronix 2012-02-26 20:01:15