2008-09-15 19 views
37

Eğer bir xib dosyasına bağlı bir UILabel gibi bir şeyim varsa, benim görüşümün bir parçası olarak onu serbest bırakmak zorunda mıyım? Sormamın sebebi, onu tahsis etmemem, bu da beni serbest bırakmamamı sağladığını mı gösteriyor? örneğin (başlığında):Xib kaynaklarını serbest bırakmalı mıyım?

IBOutlet UILabel *lblExample; 

uygulanmasında:

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

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

cevap

35

şimdi iyi uygulamayı kabul ne izlerseniz, bırakma çıkış özellikleri, gerektiği :

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


@implementation MyController 

@synthesize uiElement; 

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

Bu yaklaşımın avantajı öyle mi bellek yönetimi semantik açık ve net, yapar ve tüm platform dosyaları tüm nib dosyaları için tutarlı bir şekilde çalışır.

Not: Aşağıdaki yorumlar yalnızca 3.0'dan önceki iOS için geçerlidir. 3.0 ve üstü ile, viewDidUnload'daki özellik değerlerini geçersiz kılmanız gerekir.

Denetleyicinizin kullanıcı arabirimini elden çıkarabildiği ve isteğe bağlı olarak dinamik olarak yeniden yükleyebildiği (örneğin, bir nib dosyasından bir görünüm yükleyen bir görünüm denetleyiciniz varsa, ancak istek üzerine), burada göz önünde bulundurulması gereken bir husustur. bellek baskısı altında - görünüm yeniden gerekiyorsa, yeniden yüklenebileceği beklentisiyle, onu serbest bırakır. Bu durumda, ana görünüm bertaraf edildiğinde, başka herhangi bir satış kuruluşunun mülkiyetini de bıraktığınızdan emin olmak istersiniz, böylece onlar da tahsis edilebilir. UIViewController için, aşağıdaki gibi setView: geçersiz kılarak bu konuyla başa çıkabilirim:

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

Ne yazık ki bu bir başka soruna yol açmaktadır.UIViewController şu anda setView: erişimci yöntemini kullanarak dealloc yöntemini uygular (yalnızca doğrudan değişkeni serbest bırakmak yerine), self.anOutlet = nildealloc'da çağrılır ve bir uyarı uyarısına yanıt olarak ... Bu dealloc'da bir çökmeye neden olur.

çare o çıkış değişkenleri de dealloc yılında nil ayarlanır sağlamaktır: doğru:

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

Bir muhafaza özelliğimiz varsa, bunu basitçe self.uiElement = nil; yayınlamak istediğimiz her yerde, bir muhafaza özelliği olduğu için, onu düzgün bir şekilde serbest bırakmalı ve hiçbir şey olmadan sıfırlamaya ayarlamalıdır, özelliklerin korunmasının avantajlarından biridir. –

+1

Normalde 'self view: viewDidUnload' 'setView:' içinde 'self.uiElement = nil; Ve sadece self.anOutlet = nil; –

+2

Self.anOutlet = nil; boşta. Haklı olarak erişimcileri aramak kötü bir davranış. – tobyc

0
+1

@Soeren: Bu makaleyi zaten okudum ve içeriğini anladım. Sorum şu, kapsamı olmayan bir IB xib üzerinde başlatılan nesnelerle ilgili idi. Örn: Asla etiketi yaratmadım ya da tahsis etmedim, IB büyüsü bunu yapıyor. Yani bilmem gereken şey basit: onu serbest bırakmam gerek? – rustyshelf

0

Sen IB bunu oluşturarak, bir anlamda, etiket alloc yapmak.

IB ne yapar, IBOutlet'larınıza ve bunların nasıl tanımlandığına bakın. IB'nin bir nesneye referans atamak için bir sınıf değişkeniniz varsa, IB sizin için bu nesneye bir saklama mesajı gönderecektir.

Özellik kullanıyorsanız, IB değeri ayarlamanız ve değeri açıkça tutmanız gereken özelliği kullanacaktır. Eğer dealloc salınımını çağırmalıdır

@property (nonatomic, retain) UILabel *lblExample; 

Böylece eter durumda (kullanarak özelliklerini veya değil): Böylece korumak olarak IBOutlet özelliklerini normalde işaretlemek olacaktır.

+3

Bu doğru değil. Özellikleri kullanmıyorsanız (veya kendi erişimci yöntemlerinizi uygularsanız), serbest bırakmanız gerekip gerekmediğini ve hangi platformda olduğunuza ve süper sınıfınızın ne olduğuna bağlı olarak değişir. Örneğin NSWindowController'dan miras alırsanız, serbest bırakmazsınız. – mmalc

0

Herhangi IBOutlet olduğunu Nib'in ana görünümünün bir alt görünümünün yayınlanmasına gerek yoktur, çünkü bunlar otomatik olarak nesne oluşturma üzerine otorite mesajına gönderilir. Sizin dealloc'unuzda yayınlamanız gereken tek IBOutlet, kontrolörler veya diğer NSObject'ler gibi en üst düzey nesnelerdir. Bu, yukarıda belirtilen Apple belgesinde belirtilmiştir. Eğer set erişimcisi bunları muhafaza olmalıydı çünkü

+3

Bu aslında yanlış. Üst düzey nesneleri göndermeniz gerekip gerekmediği bir sürüm mesajı, hangi platformun kullandığınıza ve Dosya Sahipinizin hangi sınıftan devraldığına bağlıdır. Örneğin, NSWindowController'dan miras alırsa, bunları serbest bırakmanız gerekmez. – mmalc

3

[anOutlet release], anOutlet = nil; 

parçası da setview yazdım eğer tamamen gereksizdir.

+0

Bununla ne demek istiyorsun? – Casebash

+1

Aslında, bu 3.0 ve üstü değişti, anlıyorum. Şu anda -viewDidUnload'umuz var ve bu yüzden erişimcileri serbest bırakıyoruz. –

0

. Bunun nedeni, initWithNib ile tüm IBOutlets için belleğin ayrılacağıdır. Bu nedenle, kodunuzda herhangi bir bellek kalmamış veya tahsis etmemiş olsanız bile, yayınlamanız gereken özel durumlardan biridir.