2008-09-15 183 views
37

如果我有一個像UILabel鏈接到一個xib文件,我需要釋放它在我的視圖dealloc?我問的原因是因爲我沒有分配它,這讓我覺得我不需要釋放它呢? 例如(在頭):我是否需要發佈xib資源?

IBOutlet UILabel *lblExample; 

在執行:

.... 
[lblExample setText:@"whatever"]; 
.... 

-(void)dealloc{ 
    [lblExample release];//????????? 
} 

回答

35

如果按照現在被認爲是最好的做法,您應該釋放出口屬性,因爲你應該在set訪問保留了他們:

@interface MyController : MySuperclass { 
    Control *uiElement; 
} 
@property (nonatomic, retain) IBOutlet Control *uiElement; 
@end 


@implementation MyController 

@synthesize uiElement; 

- (void)dealloc { 
    [uiElement release]; 
    [super dealloc]; 
} 
@end 

這種方法的優點是它使內存管理語義清晰明瞭,,它在所有平臺上對所有的nib文件一致地工作。

注意:以下注釋僅適用於3.0之前的iOS。在3.0及更高版本中,您應該改爲在viewDidUnload中清除屬性值。

儘管如此,您的控制器可能會根據需要處理其用戶界面並動態重新加載它(例如,如果您有一個視圖控制器從nib文件加載視圖,但是根據請求 - 說內存壓力 - 釋放它,期望它可以重新加載,如果再次需要視圖)。在這種情況下,您要確保在處理主視圖時還放棄其他任何網點的所有權,以便它們也可以被釋放。對於UIViewController中,你可以通過重寫setView:如下解決這個問題:

- (void)setView:(UIView *)newView { 
    if (newView == nil) { 
     self.uiElement = nil; 
    } 
    [super setView:aView]; 
} 

很不幸,這產生了另一個問題。由於UIViewController當前使用setView:訪問器方法(而不是直接簡單釋放變量)實現其dealloc方法,所以將在dealloc中調用self.anOutlet = nil以及響應內存警告......這將導致在dealloc中發生崩潰。

補救的辦法是確保出口變量也在dealloc設置爲nil

- (void)dealloc { 
    // release outlets and set variables to nil 
    [anOutlet release], anOutlet = nil; 
    [super dealloc]; 
} 
+0

如果我們有一個保留財產,我們不能簡單地通過簡單地說 self.uiElement = nil; 我們想要發佈的所有地方,因爲它是一個保留屬性,它應該實際發佈它,並將其設置爲無,沒有問題,保留屬性的優點之一。 – 2010-11-24 13:44:26

+1

您通常會在`viewDidUnload`中執行`self.uiElement = nil;`而不是`setView:`。在dealloc中調用`self.anOutlet = nil;`會更清楚。 – 2011-01-15 14:38:38

0
+1

@Soeren:我已經閱讀過那篇文章,並瞭解它的內容。我的問題是關於在IB xib上實例化的對象,它沒有涉及。例如:我從來沒有真正創建或分配標籤,國際文憑組織的魔術就是這麼做的。所以我需要知道的很簡單:我需要發佈它嗎? – rustyshelf 2008-09-15 04:09:55

0

你做的Alloc的標籤,從某種意義上說,在IB創建它。

IB做了什麼,看看你的IBOutlets以及它們是如何定義的。如果您有一個IB類變量來分配一個對象的引用,IB會爲您發送一個保留消息給該對象。

如果您正在使用屬性,IB將利用您必須設置該值的屬性,而不是明確保留該值。因此,你通常會標示IBOutlet中屬性保留:

@property (nonatomic, retain) UILabel *lblExample; 

因此,在醚的情況下(使用性質或沒有),你應該調用釋放你的dealloc。

+3

這是不正確的。如果你不使用屬性(或者實現你自己的訪問器方法),那麼你是否應該釋放取決於你在哪個平臺上,以及你的超類是什麼。例如,如果您從NSWindowController繼承,則不會發布。 – mmalc 2008-10-11 09:50:55

0

任何IBOutlet中是您的Nib主視圖的子視圖不需要被釋放,因爲它們將在創建對象時發送autorelease消息。您需要在dealloc中釋放的唯一IBOutlet是控制器或其他NSObject的頂級對象。這一切都在上面鏈接的Apple文檔中提到。

+3

這實際上是錯誤的。無論您是否應發送頂級對象,發佈消息都取決於您使用的平臺以及文件所有者繼承的類。例如,如果它繼承自NSWindowController,則不需要釋放它們。 – mmalc 2008-10-10 15:43:03

3

[anOutlet release], anOutlet = nil; 

部分是,如果你寫的setView完全是多餘的:正確。

0

,如果你不設置IBOutlet中作爲屬性,而只是作爲一個實例變量,你仍必須將其釋放。這是因爲在initWithNib時,內存將分配給所有IBOutlet。因此,即使您沒有保留或分配代碼中的任何內存,這也是您必須釋放的特例之一。

相關問題