Swift dealloc


145

Bir görüntüleme denetleyicisinin ömrünün sonunda, bir NSNotificationCenterbildirimi kaldırmak için bir miktar temizlik yapmak istiyorum . Uygulama deallocbir Swift derleyici hatası sonucu:

Cannot override 'dealloc' which has been marked unavailable

Swift'de bir nesnenin ömrünün sonunda biraz temizlik yapmanın tercih edilen yolu nedir?

Yanıtlar:


334
deinit {
    // perform the deinitialization
}

Gönderen Swift Belgeler :

Bir sınıf örneğinin serbest bırakılmasından hemen önce bir deinitializer çağrılır. Deinitizer'ları, intializer'ların init anahtar sözcüğüyle nasıl yazıldığına benzer şekilde deinit anahtar sözcüğüyle yazarsınız. Deinitializers yalnızca sınıf türlerinde kullanılabilir.

Örneklerinizin ayrılması kaldırıldığında genellikle manuel temizlik yapmanız gerekmez. Ancak, kendi kaynaklarınızla çalışırken, kendi başınıza bazı ek temizlik yapmanız gerekebilir. Örneğin, bir dosyayı açmak ve ona bazı veriler yazmak için özel bir sınıf oluşturursanız, sınıf örneğinin serbest bırakılmasından önce dosyayı kapatmanız gerekebilir.


45
deinit {
    // perform the deinitialization
}

Swift "dealloc" için doğru cevap.

Bununla birlikte, iOS 9'daki yeniliklere, NSNotificationCenter'ın artık temizlenmesi gerekmediğini belirtmek iyidir!

https://developer.apple.com/library/content/releasenotes/Foundation/RN-FoundationOlderNotes/index.html#X10_11Notes

NSNotificationCenter

OS X 10.11 ve iOS 9.0'da NSNotificationCenter ve NSDistributedNotificationCenter artık ayrılabilecek kayıtlı gözlemcilere bildirim göndermeyecektir. Gözlemci, sıfırlama zayıf bir referans olarak depolanabiliyorsa, temeldeki depolama, gözlemciyi, alternatif olarak, nesne zayıf bir şekilde depolanamıyorsa (yani, çalışma zamanını engelleyecek özel bir tutma / bırakma mekanizmasına sahipse) sıfırlama zayıf bir referans olarak depolar. nesneyi zayıf bir şekilde saklayabilmekten), nesneyi zayıf olmayan bir sıfırlama referansı olarak depolar. Bu, gözlemcilerin serbest bırakma yöntemlerinde kayıtlarını silmelerine gerek olmadığı anlamına gelir. Bu gözlemciye yönlendirilecek bir sonraki bildirim, sıfırlanmış referansı tespit edecek ve gözlemcinin kaydını otomatik olarak kaldıracaktır. Bir nesneye zayıf bir şekilde referans verilebiliyorsa, serbest bırakma sırasında artık bildirimler gözlemciye gönderilmeyecektir; dealloc sırasında bildirim almanın önceki davranışı, zayıf bir şekilde sıfırlanmamış referans gözlemciler durumunda hala mevcuttur. - [NSNotificationCenter addObserverForName: object: queue: usingBlock] yöntemi aracılığıyla blok tabanlı gözlemcilerin, sistem bu gözlemciler için hala güçlü bir referans tuttuğundan, artık kullanımda değilken yine de kayıtlarının kaldırılması gerekir. Gözlemcilerin vaktinden önce kaldırılması (zayıf referanslı veya sıfırlama referanslı) hala desteklenmektedir. CFNotificationCenterAddObserver, gözlemci bir nesne olmayabileceğinden bu davranışa uymaz. - [NSNotificationCenter addObserverForName: object: queue: usingBlock] yöntemi aracılığıyla blok tabanlı gözlemcilerin, sistem bu gözlemciler için hala güçlü bir referans tuttuğundan, artık kullanımda değilken yine de kayıtlarının kaldırılması gerekir. Gözlemcilerin vaktinden önce kaldırılması (zayıf referanslı veya sıfırlama referanslı) hala desteklenmektedir. CFNotificationCenterAddObserver, gözlemci bir nesne olmayabileceğinden bu davranışa uymaz. - [NSNotificationCenter addObserverForName: object: queue: usingBlock] yöntemi aracılığıyla blok tabanlı gözlemcilerin, sistem bu gözlemciler için hala güçlü bir referans tuttuğundan, artık kullanımda değilken yine de kayıtlarının kaldırılması gerekir. Gözlemcilerin vaktinden önce kaldırılması (zayıf referanslı veya sıfırlama referanslı) hala desteklenmektedir. CFNotificationCenterAddObserver, gözlemci bir nesne olmayabileceğinden bu davranışa uymaz.

ancak güçlü referanslarla ilgili aşağıdaki noktalara dikkat edin, bu yüzden yine de temizlik konusunda endişelenmeniz gerekebilir ...?


3
Bildirim bloğunun güçlü bir referansı olmadığı sürece, gözlemciyi kaldırmanız gerekir.
TigerCoding

Gözlemcileri temizlemek zorunda kalmamak için +1. Bilmek önemli! Tüm yakalama referanslarını zayıflatıyorum, bu yüzden asla bununla uğraşmam.
n13

2
Belgelere göre bildirim bloklarına her zaman güçlü bir şekilde başvurulduğu görülmektedir. Yani: Eğer bildirimleri işlemek için blokları kullanıyorsanız, sahip deinit içeride onlar için kaydını silmek.
marsbear

22

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

Swift, kaynakları boşaltmak için artık ihtiyaç kalmadığında örneklerinizi otomatik olarak kaldırır. Swift, Otomatik Referans Sayma'da açıklandığı gibi otomatik referans sayma (ARC) aracılığıyla örneklerin bellek yönetimini gerçekleştirir. Örnekleriniz serbest bırakıldığında genellikle manuel temizlik yapmanız gerekmez. Ancak, kendi kaynaklarınızla çalışırken, kendi başınıza ek temizlik yapmanız gerekebilir. Örneğin, bir dosyayı açmak ve ona bazı veriler yazmak için özel bir sınıf oluşturursanız, sınıf örneğinin serbest bırakılmasından önce dosyayı kapatmanız gerekebilir.

Sınıf tanımları, sınıf başına en fazla bir başlatıcıya sahip olabilir. Deinitializer herhangi bir parametre almaz ve parantez olmadan yazılır:

deinit {
    // perform the deinitialization
}

2

serbest bırakmadan önce gözlemcinin kaldırılması gerekir, aksi takdirde çökme meydana gelebilir. Kullanılarak yapılabilir

deinit {
    // perform the deinitialization
    print("deinit")

    removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
    removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)

}

0

Görünüm kapsam dışına çıktığında gerçekten bir şeyi kaldırmak ve kapsam dahilinde başlamak istiyorsanız, bunu denetleyicinin didAppear ve didDisappear yönteminde yapalım. NSNotificationCenter bile görünüm göründüğünde / kaybolduğunda kaldırabilir ve geri ekleyebilir.


-2

Deinit'ten başka bir sınıftaki bir yöntemi çağırırken dikkatli olun , muhtemelen çökme ile sonuçlanacaktır.


1
Olumsuz oy verilmiş, çünkü durum böyle olmamalıdır. Gönderen ref. docs : Bir örnek, deinitializer çağrılana kadar serbest bırakılmadığından, bir deinitializer çağrıldığı örneğin tüm özelliklerine erişebilir ve davranışını bu özelliklere göre değiştirebilir (örneğin, kapalı olun).
superjos
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.