2011-09-03 16 views
198

Benim küçük iPad uygulamasında bir gözlemci kullanan bir "geçiş dili" işlevi var. Her görüntü denetleyicisi, viewDidLoad: sırasında kendi gözlemcim ile kendini kaydeder. Özel dealloc ve ARC (Objective-C)

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [observer registerObject:self]; 
} 

kullanıcı "dil değiştir" düğmesine vurur

, yeni bir dil benim modelinde saklanır ve gözlemci bildirilir olup kayıtlı nesneler üzerinde bir updateUi: seçici çağırır.

TabBarController'da görüntüleme denetleyicileri olduğum durumlar dışında, bu çok iyi çalışır. Bunun nedeni, sekme çubuğu yüklendiğinde, görünümleri başlatmadan sekme simgelerini çocuk denetleyicilerinden getirmesi, dolayısıyla viewDidLoad: çağrılmaması, bu nedenle görünüm denetleyicilerinin dil değişikliği bildirimleri almamasıdır. Bu nedenle, registerObject: çağrılarımı init yöntemine taşıdım.

Gözlemcimle kayıt yaptırmak için viewDidLoad: kullanıldığında, kaydını silmek için viewDidUnload: kullandım. Şimdi init'a kaydolduğumdan, dealloc'da kaydını kaldırmak çok mantıklı.

Ama burada benim sorundur. Ben yazarken:

- (void) dealloc 
{ 
    [observer unregisterObject:self]; 
    [super dealloc]; 
} 

bu hatayı alıyorum:

ARC forbids explicit message send of 'dealloc'

Ben süper sınıf düzgün temizlemek sağlamak için [super dealloc] çağırmanız gerekir, ancak ARC şimdi şaşırıp, o yasaklar beri. Nesnem öldüğünde haber almak için başka bir yolu var mı? (Clang LLVM ARC document, chapter 7.1.2 anlatıldığı gibi) derleyici sizin için kolları -

+0

- Böyle bir durum bir bellek sızıntısına neden olabilir, Sızıntı aracında görünmeyecek. Eğer dataModel, gözlemciye referans tutarsa ​​(yani ARC altında, ivarlar için bile öntanımlı olanı), alıkoyma sayısı sıfırdan büyük olacağından, asla dize alınmayacaktır. Bu nedenle, ilk önce dealloc çağrısının yapılabilmesi için gözlemcinin kaydını manuel olarak kaydetmeniz gerekebilir. –

+0

Sağ ve sol elle kullanılan seçenekler için benzer bir şey uyguladım. Mesaja ihtiyacı olan tek VC şu anda görüntülenen olanıdır. Diğerleri, arabirimde değişiklikler yapmak için viewDidLoad veya viewDidAppear'daki modele bakar. Belki böyle bir şey daha iyi çalışırdı. –

+0

@BlazejCzapp bir UITabBarController kullandığı için, ve UITabBarController'ın her zaman kayıtlı denetleyiciye bir referans göstereceğini varsayalım (sanırım 'çocuk' denetleyicilerinde olduğu gibi), bellek sızıntısı hala bir sorun olur mu? Kayıtlı denetleyicinin ne zaman ayrılacağını göremiyorum. Teşekkürler – Objectif

cevap

400

ARC kullanarak, sadece [super dealloc] açıkça demiyorlar:

Bir yan not olarak
- (void) dealloc 
{ 
    [observer unregisterObject:self]; 
    // [super dealloc]; //(provided by the compiler) 
} 
+2

Görünüm, gözlemciye bir başvuru içeriyorsa ve gözlemci görünüme başvurursa, o zaman dairesel bir referansımız vardır. Böylece görüşün referans sayısı 0'dan büyüktür ve "dealloc" asla çağrılmaz. '[Gözlemci unregisterObject: self] 'işlevini dealloc olarak adlandırmak mantıklı mı? Neyi kaçırıyorum? – user443854

+0

iş ister. Gözlemcinin kontrolöre bir referans göstermesine sebep olur. ilk etapta çağrılmanın dürüstlüğünü engelleyecek – hasan83