2011-12-19 79 views
1

我有幾個UIView子類(按鈕,標籤等)遵循以下安裝模式。我的問題是,爲什麼郵件仍然可以在release之後發送到UILabel將消息發送到發佈的對象?

myLabel = [[UILabel alloc] initWithFrame:someFrame]; 
    [someUIView addSubview:myLabel]; 
    [myLabel release]; 

    myLabel.textAlignment = UITextAlignmentCenter; 

    // other property changes to myLabel 

他們被新的UIView「擁有」,我想,但我不明白爲什麼release不破壞原來的對象,因而所有的消息吧。我不通過someUIViewsubViews進行財產更改。我沒有抱怨。我只是想明白爲什麼。

編輯:我應該補充說,這些是實例變量,如果這有所作爲。

回答

1

,您仍然可以將消息發送到標籤,因爲標籤還沒有被釋放。 -addSubview:保留傳入的對象,因此該對象保留在內存中,因爲該視圖仍然保存引用,並且您沒有指定myLabel指針。

+0

完美!謝謝!我如何知道另一種方法何時會隱式調用發佈?有一些我應該知道的清單嗎? (除了查看NSObject的retainCount) – 2011-12-19 00:49:35

+1

釋放一個對象後不要使用它。 – zaph 2011-12-19 00:52:51

+2

簡短的回答是......不用擔心。當然,我碰巧知道'-addSubview:'在對象上執行保留,但這不是必需的。至於'retainCount',就不要打擾。認真。這是一個只會導致瘋狂的實現細節。 – 2011-12-19 00:53:53

0

因爲他們可能之前保留...

+0

這就是我想,但經過進一步檢查,我看不出有什麼明顯的先保留。 – 2011-12-19 00:39:48

1

當您收到它時,您致電-addSubview:時會在標籤上標註-retain。此時,您放棄所有權(通過呼叫-release),只有視圖擁有它。但它仍然存在,直到包含視圖也釋放它。

3

只要保留計數大於0,對象就不會被破壞。在這種情況下,someUIView保留了該對象。

最好不要在釋放對象後訪問對象。一個更好的模式可能是:

myLabel = [[[UILabel alloc] initWithFrame:someFrame] autorelease]; 
myLabel.textAlignment = UITextAlignmentCenter; 
[someUIView addSubview:myLabel]; 
myLabel = nil; 

第二個例子:

myLabel = [[UILabel alloc] initWithFrame:someFrame]; 
[someUIView addSubview:myLabel]; 
myLabel.textAlignment = UITextAlignmentCenter; 

// other property changes to myLabel 

[myLabel release]; 
myLabel = nil; 
+0

我在發佈之後發生屬性更改的唯一原因是因爲該類中的其他方法正在更改它們。如果在任何特定時間,我不確定還有什麼地方可以發佈,另一種方法可能會改變它的屬性。 – 2011-12-19 00:52:55

+0

然後在設置'textAlignment'後釋放,參見我的第二個例子。一個建議「使用ARC,它會處理所有的保留和釋放。 – zaph 2011-12-19 01:10:21

+0

如果'myLabel'是一個實例變量,並且你的類中的其他方法可能會改變'myLabel',那麼每一個更改應該先釋放現有的值,然後重新分配。但是,這聽起來非常脆弱,如果那真的是這樣的話;你如何確保這個'textAlignment'保持一致? – bbum 2011-12-19 03:49:49