Özel dealloc ve ARC (Objective-C)


208

Küçük iPad uygulamamda bir gözlemci kullanan bir "dil değiştirme" fonksiyonum var. Her görünüm denetleyicisi, sırasında gözlemcime kendini kaydeder viewDidLoad:.

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

Kullanıcı "dili değiştir" düğmesine bastığında, yeni dil modelime kaydedilir ve gözlemci bilgilendirilir ve updateUi:kayıtlı nesneleri üzerinde bir seçici çağırır .

TabBarController içinde görünüm denetleyicileri olduğunda bu çok iyi çalışıyor. Bunun nedeni, sekme çubuğu yüklendiğinde, görünümleri başlatmadan sekme simgelerini alt denetleyicilerinden alır, bu nedenle viewDidLoad:çağrılmaz, bu nedenle bu görünüm denetleyicileri dil değişikliği bildirimleri almaz. Bu nedenle, registerObject:çağrılarımı inityönteme taşıdım .

viewDidLoad:Gözlemcime kayıt olurken ,viewDidUnload: unregister için. Şimdi kaydolduğumdan beri kayıt olmak initçok mantıklı dealloc.

Ama işte benim sorunum. Yazarken:

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

Bu hatayı alıyorum:

ARC, 'dealloc'un açık mesaj göndermesini yasakladı

[super dealloc]Üst sınıfların düzgün bir şekilde temizlenmesini sağlamak için aramam gerektiğinden, ancak ARC bunu yasakladı, şimdi sıkıştım. Nesnem ölürken haberdar olmanın başka bir yolu var mı?


Bir yan not olarak - böyle bir durum, Sızıntılar aracında görünmeyecek bir bellek sızıntısına neden olabilir. DataModel gözlemciye olan referansı korursa (ivar'lar için bile ARC altında varsayılan şeydir), tutma sayısı sıfırdan büyük olacağından, dealloc asla çağrılmaz. Bu nedenle, dealloc'un ilk etapta çağrılmasını sağlamak için gözlemciyi manuel olarak silmeniz gerekebilir.
Błażej Czapp

Sağ ve sol el seçenekleri için benzer bir şey uyguladım. İletiye ihtiyaç duyan tek VC, o anda görüntülenen değerdir. Diğerleri arayüzde değişiklik yapmak için viewDidLoad veya viewDidAppear'daki modele bakar. Belki böyle bir şey daha iyi çalışır.
Doug Watkins

@BlazejCzapp bir UITabBarController kullandığı için ve diyelim ki UITabBarController her zaman kayıtlı kontrolöre bir referans tutacaktır ('çocuk' kontrol cihazlarında olduğu gibi), bellek sızıntısı hala bir sorun olacak mı? Kayıtlı denetleyicinin ne zaman tahsis edileceğini görmüyorum. Teşekkürler
Objectif

Yanıtlar:


419

ARC kullanırken, sadece [super dealloc]açıkça aramazsınız - derleyici bunu sizin için yapar ( Clang LLVM ARC belgesinde, bölüm 7.1.2'de açıklandığı gibi ):

- (void) dealloc
{
    [observer unregisterObject:self];
    // [super dealloc]; //(provided by the compiler)
}

4
Eğer görüş gözlemciye bir referansa sahipse ve gözlemci görüşe referansta bulunuyorsa, o zaman dairesel bir referansımız olur. Dolayısıyla görünümün referans sayısı 0'dan büyüktür ve deallocasla çağrılmaz. [observer unregisterObject:self]Dealloc'da aramak mantıklı mı ? Neyi kaçırıyorum?
user443854

bu iş istiyor. çünkü gözlemcinin kendisi denetleyiciye bir referans tutar. bu ilk etapta çağrılmayı önleyecek
hasan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.