2011-09-30 58 views
0

假設,對於A類對象的所有權,「返回」後。澄清所需

@property(nonatomic, assign) DoublyLinkedList *doublyLinkedList; 

下面的聲明,作爲初始化的一部分,初始化的對象

- (id)init { 
    self = [super init]; 
    if (self) { 
     doublyLinkedList = [[DoublyLinkedList alloc] init]; 
    } 

    return self; 
} 

和方法

- (DoublyLinkedList*) doSomethingAndReturn { 

最終

return doublyLinkedList; 

A班是否在返回後擁有doublyLinkedList

回答

2

編輯:添加initalloc

你是不是要求它retain,但在init你調用它alloc,所以它確實有一個1保留計數 - 你擁有它,你應該釋放它在dealloc

您可以簡單地alloc它並釋放它在dealloc。該物業的來電者可以選擇是否保留。另一種選擇是在init中創建對象,然後將其自動釋放,然後使用(retain)而不是(assign)將其分配給該屬性。這樣,如果代碼alloc中的其他地方並分配給該屬性,則您將獲得釋放的對象爲alloc。然後在dealloc,它目前分配的內容將被釋放。

另一種選擇,如果你不想讓別人設置它將是一個(readonly)財產和一個_doubleLinkedList iVar然後@synthesize doublyLinkedList = _doubleLinkedList。然後你可以在init中分配一次,並知道其他人不會分配它,然後在dealloc中釋放它。

一個很好的比喻是,當你保留下來的時候,你就會對它施加壓力。多個項目可以在該對象上放置皮帶。只有當每個人都把皮帶掉的時候它纔會被釋放出來。

一個很好的指導閱讀:

Apple's Memory Management Programming Guide

從DOC

具體而言,這些規則的幫助:

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

您可以使用所有權保留一物體接收的對象 通常是保證它是 方法內仍然有效收到,而且方法也可以安全地將對象返回到其 調用。在兩種情況下使用retain:(1)在訪問器方法或init方法的實現 中,獲取要作爲屬性值存儲的 對象的所有權; (2)爲防止 對象作爲其他操作 的副作用而失效(如「避免導致對象的取消分配您正在使用 」所述)。

當你不再需要它,你必須放棄一個 對象的所有權您擁有您可以通過發送一個 釋放消息或一個自動釋放消息的放棄對象的所有權。在Cocoa術語中,放棄對象的所有權通常因此被稱爲「釋放」對象。

你一定不會放棄對象的所有權不屬於您這 是對先前的策略規則只是推論,明確說明。

+0

好的。所以要回答我的問題,「不」,「返回」本身不會放棄對班級創建的任何控制。 – JAM

+0

@mac正確。返回不觸及對象,它只是將引用傳遞給調用者。 –

+0

是的 - 像肯尼說:) – bryanmac

1

物體並非真的「擁有」。當保留計數變爲0時,Objective-C將釋放對象的內存。只要類A的實例處於活動狀態,如果類A依賴於doubleLinkedList「保持活動狀態」,則對象A將保留雙向鏈接列表以增加保留計數1.當對象A如上所述返回對doublyLinkedList的引用時,那麼接收該結果的調用者也可以選擇保留該對象,這會再次將保留計數增加1。

所以儘量不要把它看作擁有一個對象。相反,把它看作是表達對一個對象存在的興趣。只要某人繼續對該對象感興趣,就像其保留計數所表示的那樣,則該對象將不會被釋放。

1

正如您所定義的那樣,類A從來沒有保留雙向鏈表。所以不,它沒有任何利害關係。事實上,因爲doublyLinkedList不是由類A保留的,所以在執行過程中可以隨時解除分配,並導致EXEC_BAD_ACCESS崩潰。

有兩種明顯的方法可以解決這個問題。

  1. A類應該在使用它時保留doublyLinkedList,並在它返回之前自動釋放它。
  2. 另一個'父'對象可以同時保留doublyLinkedList和類A的實例,並且它取決於'父'對象,以確保在A類對象正在使用它時,doublyLinkedList不會被釋放。

編輯:

如果你的alloc-初始化對象時,你初始化類,如你在上面添加,那麼當一個類被釋放,你應該只釋放對象。這使得一個簡單的對象生命週期。類A的一個實例被創建,它創建一個DLL對象。該對象一直存在,直到類A實例被銷燬。如果其他對象想要使用DLL,他們只需從A類實例中請求它並保留它。

與目標保留髮布是這樣一種方式,你可以確保你有一個偶數保持通話編碼,並在對象上呼籲釋放。對於每一個:

- (id)init { 
    self = [super init]; 
    if (self) { 
    doublyLinkedList = [[DoublyLinkedList alloc] init]; 
    } 

    return self; 
} 

您需要:

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

如果你的類的對象將被創建和處理多個DLL對象,則不要在-(id)init創建和使用retain爲財產申報。 然後:

ClassA *newClassAObject = [[ClassA alloc] init]; // create class a object 
newClassAObject.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease]; // make a DLL object, only retained by class a object. 
DoublyLinkedList *dll = [newClassAObject doSomethingAndReturn]; // process the list somehow 
[dll retain] // we own this now 
newClassAObject.doublyLinkedList = nil; // class A object gives up interest in dll. 
newClassAObject.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease]; // now process another one. 
... and on and on ... 
+0

等一下..類'A',通過創建'頁頭init'的DLL。這不是「保留」它嗎? – JAM

+0

如果你在init中分配它(最初沒有看到),那麼你確實擁有它並在dealloc中釋放它。也許我讀錯了,但最初我雖然只是沒有保留的屬性和返回的方法。回報沒有做任何事情。 – bryanmac

+0

+1對EXEC_BAD_ACCESS – bryanmac