2011-02-02 12 views
2

我讀過蘋果文檔來斷言我正在正確地進行內存管理,但提出了一些問題。iOS objective-c返回對象可用性/範圍

問題1:

他們表現出此代碼段爲錯:

in obj implementation: 
- (NSString *)method1 { 
    NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName]; 
    return string; 
} 

... later ... 

NString* myString = [obj method1]; 
NSLog("%@", myString); 
[myString release]; 

Apple Doc

You own the string returned by alloc, but lose the reference to it before you get a chance to relinquish ownership. Following the memory management rules, this would result in a memory leak, since the caller has no indication that they own the returned object. 

因爲我正在釋放先前已分配對象的護理,沒有內存泄漏,對吧? 「失去對它的引用」是什麼意思?

關於蘋果的內存管理建議(調用者沒有跡象表明他們擁有返回的對象)這是錯誤的,或者這在技術上也是錯誤的?

問題2:

這是一個關於自動釋放對象的可用性:

示例代碼:

in obj1 implementation: 
- (NSString *)methodA { 
    NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName]; 
    return [string autorelease]; 
} 

in obj2 implementation: 
- (NSString *)methodB:(NSString *)inputString { 
    NSLog("%@",inputString) 
    //*other call of methods with arg inputString*// 
} 
... later ... 

NString* myString = [obj1 methodA]; 

[obj2 method2:myString]; 

多遠(或深)以下我的函數的調用將自動釋放對象由OBJ1返回會能得到的。關於蘋果的文檔「Autorelease對象將在其變量範圍內可用」。我應該在某個時候保留它嗎?

+0

本文可能會幫助任何正在尋找關於此問題的更多解釋的人。 http://www.asgteach.com/blog/?p=73 – 2013-03-12 18:30:31

回答

4

Q1:這是錯誤的只是關於蘋果的內存管理的建議(呼叫者沒有跡象表明他們擁有返回的對象),或者這也是技術上的錯誤?

從技術上講,使用它後釋放myString是正確的。但是,如果你按照蘋果guidelines for method naming強烈推薦),這顯然是錯誤的:

您自己創建的任何對象。 使用名稱以「alloc」或「new」開頭或包含「copy」(例如alloc,newObject或mutableCopy)的方法「創建」一個對象。

method1不含createallocnewcopy - 因此每方針調用方不擁有該對象,並沒有將其釋放。

Q2:多遠(或深)以下我的函數的調用將返回OBJ1的自動釋放對象將可用。關於蘋果的文檔「Autorelease對象將在其變量範圍內可用」。我應該在某個時候保留它嗎?

自動釋放的對象一定會健在,直到最近的自動釋放池被排空,見Autorelease Pools

自動釋放池是NSAutoreleasePool的一個實例是「包含」已經收到一個自動釋放消息的其他對象;當autorelease池被釋放時,它向每個對象發送釋放消息。一個對象可以被放入一個自動釋放池中幾次,並在每次放入池中時都會收到一條釋放消息。因此,向對象發送autorelease而不是release會延長該對象的生命週期,至少在池本身被釋放之前(如果該對象在過渡期間被保留,則該對象可以存活更長時間)。
...
Application Kit會在事件循環(或事件循環迭代)的開始處自動創建一個池,如鼠標停止事件,並在最後釋放它,因此您的代碼通常沒有擔心他們。有三種情況,不過,在這裏你可以使用自己的自動釋放池:
...

所以,如果你需要你的情況下,爲了生存相應的自動釋放池被抽乾後,採取所有權通過保留他們。否則,你通常只是讓他們在游泳池裏處理。

+0

感謝您的答案! – Kami 2011-02-02 11:35:27

3

由於我正在照顧釋放先前分配的對象,沒有內存泄漏,對吧?

他們是什麼意思是 「失去對它的引用」?

您不保留對象的指針,這樣對象可能無法在您的程序中訪問。

只有關於蘋果的內存管理建議(調用者沒有跡象表明他們擁有返回的對象),或者這在技術上也是錯誤的,這是錯誤的嗎?

也正確。靜態分析器也會大大地哭泣

在我的函數調用後面多遠(或深)將由obj1返回的autorelease對象將可用。關於蘋果的文檔「Autorelease對象將在其變量範圍內可用」。我應該在某個時候保留它嗎?

這有點複雜。自動釋放池通過線程相互堆疊。這就是爲什麼在進入線程或新事件循環迭代時必須創建一個,以及爲什麼在執行創建許多(自動釋放)分配的大操作時明確創建它們是一個好主意。

最後,堆棧中的最後一個池(對於線程)在運行循環迭代結束時被銷燬。

如果該對象是在您明確創建的自動釋放池下創建的,那麼您必須保留該對象以在創建它的池的生命週期之外使用它。

類似地,傳遞給其他線程時必須正式保留/複製。通常,這種情況會立即發生 - 您只需在進入輔助線程的實現時創建副本或保留正式參數。