Haruskah deinit diganti untuk menghapus pengamat di Swift?

Rekan tim menulis kode seperti,

deinit {
    NotificationCenter.default.removeObserver(self)
}

Saya berkomentar untuk menghapus ini karena pengamat sudah diperhatikan oleh kerangka kerja tersebut. Rekan satu tim ingin menyimpan kode ini jika tidak ada efek samping. Sekarang, meskipun kita tetap menyimpan kode di atas, apakah ada efek sampingnya?

Haruskah saya juga menelepon super.deinit() di dalam deinit?


person Sazzad Hissain Khan    schedule 24.02.2020    source sumber
comment
Apakah Anda bertanya apakah deinit harus ditimpa secara umum (seperti yang ditunjukkan dalam judul) atau harus ditimpa untuk menghapus pengamat?   -  person Martin R    schedule 24.02.2020
comment
@MartinR mengubah judul   -  person Sazzad Hissain Khan    schedule 24.02.2020
comment
Bandingkan stackoverflow.com/q/25069480/1187415 dan stackoverflow.com/q/53394779/1187415.   -  person Martin R    schedule 24.02.2020
comment
@MartinR jawaban postingan pertama sudah 6 tahun ke belakang (Saya mendengar ada beberapa perubahan di ARC) dan jawaban postingan kedua tidak menunjukkan masalahnya.   -  person Sazzad Hissain Khan    schedule 24.02.2020


Jawaban (2)


Mulai iOS 9, Anda tidak perlu menghapus sendiri pengamat, jika Anda tidak menggunakan pengamat berbasis blok. Sistem akan melakukannya untuk Anda, karena sistem ini menggunakan referensi zeroing-weak untuk pengamat, jika memungkinkan.

Jika pengamat dapat disimpan sebagai referensi yang lemah, penyimpanan yang mendasarinya akan menyimpan pengamat sebagai referensi yang lemah, sebagai alternatif jika objek tidak dapat disimpan dengan lemah (yaitu ia memiliki mekanisme penyimpanan/pelepasan khusus yang akan mencegah runtime dari kemampuan untuk menyimpan objek dengan lemah) itu akan menyimpan objek sebagai referensi zeroing yang tidak lemah. Artinya, pengamat tidak diharuskan untuk membatalkan pendaftaran dalam metode dealokasinya.

Pengamat berbasis blok melalui metode -[NSNotificationCenter addObserverForName: object: queue: usingBlock] masih perlu dibatalkan pendaftarannya ketika tidak lagi digunakan karena sistem masih menyimpan referensi kuat ke pengamat ini.

Apple Docs

dan untuk super.deinit() kata apple

Deinitializer dipanggil secara otomatis, tepat sebelum deallokasi instance terjadi. Anda tidak diperbolehkan memanggil deinitializer sendiri. Deinitializer superclass diwarisi oleh subclassnya, dan deinitializer superclass dipanggil secara otomatis di akhir implementasi deinitializer subclass. Deinitializer superclass selalu dipanggil, meskipun subclass tidak menyediakan deinitializer sendiri.

dokumen cepat

person Jawad Ali    schedule 24.02.2020

Ya, itu valid untuk ditimpa

deinit()

Seperti yang ditunjukkan dalam komentar. Super tidak perlu dipanggil. Saya mengkonfirmasi ini di dokumen Apple.

Membersihkan secara eksplisit adalah ide yang bagus. Terutama dalam hal threading, notifikasi, dan timer.

person Woodstock    schedule 24.02.2020
comment
super.deinit()dipanggil secara implisit di Swift, Anda tidak dapat memanggilnya secara eksplisit: “error: Deinitializers tidak dapat diakses” - person Martin R; 24.02.2020