Customallalloc dan ARC (Objective-C)

208

Di aplikasi iPad kecil saya, saya memiliki fungsi "ganti bahasa" yang menggunakan pengamat. Setiap view controller mendaftar sendiri dengan pengamat saya selama itu viewDidLoad:.

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

Ketika pengguna menekan tombol "ganti bahasa", bahasa baru disimpan dalam model saya dan pengamat diberitahu dan memanggil updateUi:pemilih pada objek yang terdaftar.

Ini bekerja dengan sangat baik, kecuali ketika saya memiliki pengontrol tampilan di TabBarController. Ini karena ketika bilah tab dimuat, ikon ikon mengambil tab dari pengontrol anak tanpa menginisialisasi tampilan, jadi viewDidLoad:tidak dipanggil, sehingga pengontrol tampilan tersebut tidak menerima pemberitahuan perubahan bahasa. Karena itu, saya memindahkan registerObject:panggilan saya ke initmetode.

Dulu ketika saya viewDidLoad:mendaftar dengan pengamat saya, saya biasanya viewDidUnload:tidak mendaftar . Karena saya sekarang mendaftar init, masuk akal untuk membatalkan pendaftaran dealloc.

Tapi ini masalah saya. Ketika saya menulis:

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

Saya mendapatkan kesalahan ini:

ARC melarang pengiriman pesan eksplisit 'dealloc'

Karena saya perlu menelepon [super dealloc]untuk memastikan superclasses membersihkan dengan benar, tetapi ARC melarang itu, saya sekarang terjebak. Apakah ada cara lain untuk mendapat informasi ketika objek saya sekarat?

Niku
sumber
Sebagai catatan - situasi seperti ini dapat menyebabkan kebocoran memori, yang tidak akan ditampilkan di alat Kebocoran. Jika dataModel mempertahankan referensi ke pengamat (yang merupakan hal default di bawah ARC, bahkan untuk ivars), dealloc tidak akan pernah dipanggil, karena jumlah retain akan lebih besar dari nol. Jadi, Anda mungkin harus membatalkan registrasi pengamat untuk mengaktifkan dealloc secara manual.
Błażej Czapp
Saya menerapkan sesuatu yang serupa untuk opsi tangan kanan dan kiri. Satu-satunya VC yang membutuhkan pesan adalah yang saat ini ditampilkan. Orang lain melihat model di viewDidLoad atau viewDidAppear untuk membuat perubahan pada antarmuka. Mungkin sesuatu seperti ini akan bekerja lebih baik.
Doug Watkins
@BlazejCzapp karena dia menggunakan UITabBarController, dan katakanlah UITabBarController akan selalu memegang referensi ke kontroler terdaftar (seperti yang saya duga adalah kasus dengan pengendali 'anak'), apakah kebocoran memori masih menjadi masalah? Saya tidak melihat kapan kontroler terdaftar akan dialokasikan. Terima kasih
Objectif

Jawaban:

419

Saat menggunakan ARC, Anda tidak perlu menelepon [super dealloc]secara eksplisit - kompilator menanganinya untuk Anda (seperti yang dijelaskan dalam dokumen Dentang LLVM ARC, bab 7.1.2 ):

- (void) dealloc
{
    [observer unregisterObject:self];
    // [super dealloc]; //(provided by the compiler)
}
justin
sumber
4
Jika tampilan memegang referensi ke pengamat, dan pengamat memegang referensi ke tampilan, maka kita memiliki referensi melingkar. Jadi jumlah referensi tampilan lebih besar dari 0, dan dealloctidak pernah dipanggil. Apakah masuk akal untuk memanggil [observer unregisterObject:self]dealloc? Apa yang saya lewatkan?
user443854
itu ingin bekerja. karena pengamat itu sendiri memegang referensi ke controller. yang akan mencegah dealloc dipanggil di tempat pertama
hasan