如果我有一個像UILabel鏈接到一個xib文件,我需要釋放它在我的視圖dealloc?我問的原因是因爲我沒有分配它,這讓我覺得我不需要釋放它呢? 例如(在頭):我是否需要發佈xib資源?
IBOutlet UILabel *lblExample;
在執行:
....
[lblExample setText:@"whatever"];
....
-(void)dealloc{
[lblExample release];//?????????
}
如果我有一個像UILabel鏈接到一個xib文件,我需要釋放它在我的視圖dealloc?我問的原因是因爲我沒有分配它,這讓我覺得我不需要釋放它呢? 例如(在頭):我是否需要發佈xib資源?
IBOutlet UILabel *lblExample;
在執行:
....
[lblExample setText:@"whatever"];
....
-(void)dealloc{
[lblExample release];//?????????
}
如果按照現在被認爲是最好的做法,您應該釋放出口屬性,因爲你應該在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];
}
@Soeren:我已經閱讀過那篇文章,並瞭解它的內容。我的問題是關於在IB xib上實例化的對象,它沒有涉及。例如:我從來沒有真正創建或分配標籤,國際文憑組織的魔術就是這麼做的。所以我需要知道的很簡單:我需要發佈它嗎? – rustyshelf 2008-09-15 04:09:55
你做的Alloc的標籤,從某種意義上說,在IB創建它。
IB做了什麼,看看你的IBOutlets以及它們是如何定義的。如果您有一個IB類變量來分配一個對象的引用,IB會爲您發送一個保留消息給該對象。
如果您正在使用屬性,IB將利用您必須設置該值的屬性,而不是明確保留該值。因此,你通常會標示IBOutlet中屬性保留:
@property (nonatomic, retain) UILabel *lblExample;
因此,在醚的情況下(使用性質或沒有),你應該調用釋放你的dealloc。
這是不正確的。如果你不使用屬性(或者實現你自己的訪問器方法),那麼你是否應該釋放取決於你在哪個平臺上,以及你的超類是什麼。例如,如果您從NSWindowController繼承,則不會發布。 – mmalc 2008-10-11 09:50:55
我在Apple文檔中找到了我正在尋找的東西。總之,你可以設置你的對象爲你釋放和保留(或只是@property,@synthesize)屬性,但你不必搞什麼UILabels:
任何IBOutlet中是您的Nib主視圖的子視圖不需要被釋放,因爲它們將在創建對象時發送autorelease消息。您需要在dealloc中釋放的唯一IBOutlet是控制器或其他NSObject的頂級對象。這一切都在上面鏈接的Apple文檔中提到。
這實際上是錯誤的。無論您是否應發送頂級對象,發佈消息都取決於您使用的平臺以及文件所有者繼承的類。例如,如果它繼承自NSWindowController,則不需要釋放它們。 – mmalc 2008-10-10 15:43:03
的
[anOutlet release], anOutlet = nil;
部分是,如果你寫的setView完全是多餘的:正確。
如果你不釋放dealloc它會增加內存佔用。
,如果你不設置IBOutlet中作爲屬性,而只是作爲一個實例變量,你仍必須將其釋放。這是因爲在initWithNib時,內存將分配給所有IBOutlet。因此,即使您沒有保留或分配代碼中的任何內存,這也是您必須釋放的特例之一。
如果我們有一個保留財產,我們不能簡單地通過簡單地說 self.uiElement = nil; 我們想要發佈的所有地方,因爲它是一個保留屬性,它應該實際發佈它,並將其設置爲無,沒有問題,保留屬性的優點之一。 – 2010-11-24 13:44:26
您通常會在`viewDidUnload`中執行`self.uiElement = nil;`而不是`setView:`。在dealloc中調用`self.anOutlet = nil;`會更清楚。 – 2011-01-15 14:38:38