Oke, ini kesepakatannya, saya benci mengajukan pertanyaan tentang debugging dan crash saya. Karena saya biasanya menanganinya sendiri, tetapi saya tidak bisa mengatasi hal ini, bahkan setelah melihat beberapa pertanyaan .
Oke jadi inilah masalahnya, saya menemukan aplikasi saya secara acak dan mati dengan pelacakan tumpukan ini:
*** -[ViewController respondsToSelector:]: message sent to deallocated instance 0x1e5d2ef0
Di mana ViewController
dapat bervariasi, kadang-kadang tempat di mana kode saya mogok, TIDAK memiliki relevansi dengan hal itu ViewController
dan tidak memiliki atau menyebutnya.
Juga, untuk mendapatkan jejak konsol itu, saya telah mengaktifkan Zombies, jika tidak saya tidak akan mendapatkan cetakan konsol sama sekali, saya hanya akan mendapatkan:, objc_msgSend
yang saya tahu berarti saya mengirim pesan sesuatu yang dirilis. Tetapi saya tidak dapat menemukan di mana itu ... Saya benar-benar terjebak! Biasanya saya selalu men-debug kerusakan saya, jadi saya benar-benar terjebak dalam hal ini.
Sekali lagi, ini crash di tempat yang berbeda pada waktu yang berbeda, on dan off. Dan tempat terjadinya crash hampir tidak ada relevansinya dengan ViewController
. Dan menurut saya ini sangat membingungkan.
Apakah Anda memerlukan kode saya? Saya memiliki banyak file dan karena macet di berbagai tempat, mendistribusikan kode saya akan berantakan!
Saya telah mencoba menambahkan breakpoint simbolis tetapi tidak berhasil, dan Zombies tidak tersedia di aplikasi Instrumen untuk iOS. Saya tidak dapat menjalankan aplikasi saya di simulator karena memiliki kerangka kerja arsitektur yang tidak mendukung.
Terimakasih semuanya...
sumber
Jawaban:
Gunakan Instrumen untuk melacak kesalahan instance yang dibatalkan alokasinya. Profil aplikasi Anda ( Cmd ⌘+ I) dan pilih template Zombies . Setelah aplikasi Anda berjalan, coba hancurkan. Anda harus mendapatkan sesuatu seperti itu:
Klik panah di sebelah alamat di popover untuk menampilkan objek yang dipanggil setelah dialokasikan.
Anda harus melihat sekarang setiap panggilan yang telah mengubah jumlah tetap dari objek ini. Ini bisa jadi karena mengirim pesan pertahankan / rilis secara langsung serta menguras kumpulan rilis otomatis atau menyisipkan ke dalam NSArays.
Kolom RefCt menunjukkan retretCount setelah tindakan dipanggil dan Penelepon yang Bertanggung Jawab menunjukkan nama kelas dan metode yang digunakan untuk melakukannya. Ketika Anda mengklik dua kali pada retensi / rilis, instrumen akan menunjukkan kepada Anda baris kode di mana ini dilakukan (Jika ini tidak berfungsi, Anda dapat memeriksa panggilan dengan memilihnya dan memilih mitranya di panel Detail Diperluas ):
Ini akan membiarkan Anda memeriksa semua daur hidup objek retretCount dan mungkin Anda akan segera menemukan masalah Anda. Semua harus Anda lakukan adalah menemukan hilang mempertahankan untuk terbaru rilis .
sumber
release
, secara spesifik. Masalahnya adalah setiap tidak seimbangrelease
. Saya juga bisa menjadi kegagalan untukretain
sesuatu yang Anda simpan petunjuknya dan rujuk nanti.punya masalah serupa. Dalam kasus saya, viewController perlu mendapatkan peristiwa navigationController, jadi ia mendaftar sebagai delegasi pengontrol navigasi:
Crash terjadi ketika pengontrol tersebut dibatalkan alokasinya tetapi masih menjadi delegasi untuk pengontrol tampilan. Menambahkan kode ini di dealloc tidak berpengaruh:
karena pada saat dealloc dipanggil, pengontrol tampilan telah dihapus dari hierarki tampilan, jadi self.navigationController nihil, jadi perbandingannya dijamin gagal! :-(
Solusinya adalah menambahkan kode ini untuk mendeteksi VC yang meninggalkan hierarki tampilan sebelum ia benar-benar melakukannya. Ini menggunakan metode yang diperkenalkan di iOS 5 untuk menentukan kapan tampilan dimunculkan dan tidak didorong
Tidak ada lagi crash!
sumber
Bagi siapa pun yang tidak bisa menyelesaikannya, berikut beberapa teknik lainnya:
https://stackoverflow.com/a/12264647/539149
https://stackoverflow.com/a/5698635/539149
https://stackoverflow.com/a/9359792/539149
https://stackoverflow.com/a/15270549/539149
https://stackoverflow.com/a/12098735/539149
Anda dapat menjalankan Instrumen di Xcode 5 dengan mengklik popup proyek-> Edit Skema ... Profil -> Instrumen dan pilih Alokasi atau Kebocoran, lalu buat profil aplikasi Anda, lalu hentikan Instrumen, klik tombol info di Alokasi dan "Aktifkan Deteksi NSZombie" .
Namun, untuk pesan yang datang langsung dari com.apple.main-thread, ini mungkin tidak akan mengungkapkan apa pun.
Saya membenturkan kepala saya pada ini selama lebih dari dua jam dan jawabannya ternyata adalah rilis berlebihan, yang saya temukan dengan mengomentari salinan proyek saya dengan kekerasan sampai saya menemukan pelakunya:
Masalahnya adalah rilis tidak menyetel variabel ke NULL.
Itu berarti bahwa menyetelnya ke panggilan NULL rilis lagi, mengurangi refcount dan mengosongkan memori segera sampai nanti ketika variabel yang mereferensikan viewController selesai dengannya.
Jadi, aktifkan ARC atau pastikan proyek Anda secara konsisten menggunakan rilis atau NULL tetapi tidak keduanya. Preferensi saya adalah menggunakan NULL karena dengan demikian tidak ada peluang untuk mereferensikan zombie tetapi itu membuat menemukan di mana objek dilepaskan lebih sulit.
sumber
Saya telah menemui masalah yang sama di iOS kemarin. Saya telah membuat IAP di subview "Tentang" Aplikasi, dan saya telah menambahkan Pengamat Transaksi di "Tentang" viewDidLoad. Ketika saya membeli untuk pertama kalinya, tidak ada masalah, tetapi setelah saya kembali ke jendela utama dan masuk tentang subview untuk membeli lagi, masalah "pesan dikirim ke contoh yang dibatalkan alokasinya" terjadi, dan Aplikasi macet.
Setelah saya menghapus Transaction Observer di dealloc, masalah terpecahkan.
sumber
zombie
objek untuk pembelian inApp. Setelah berjam-jam menggali, saya menemukan yang satu ini .... A BIG THANKS Man.Saya memiliki masalah yang sangat mirip dan saya tahu itu karena set delegasi pengontrol navigasi.
Di bawah ini memecahkan masalah saya,
sumber
Punya masalah yang sama di OS X.
Untuk mengatasi
- (void)dealloc
metode ini tidak cukup seperti yang sudah dikatakan @SoftwareEvolved. Namun sayangnya- (void)viewWillDisappear
hanya tersedia pada versi 10.10 dan yang lebih baru.Saya memperkenalkan metode kustom di subkelas NSViewController saya di mana mengatur semua referensi berbahaya-zombie menjadi nihil. Dalam kasus saya, itu adalah
NSTableView
properti (delegate
dandataSource
).Itu saja. Setiap kali saya akan menghapus tampilan dari superview perlu memanggil metode ini.
sumber
Saya memiliki masalah yang sama. Sulit untuk menemukan masalah penyebab delegasi mana, karena tidak menunjukkan pernyataan baris atau kode apa pun Jadi saya telah mencoba beberapa cara, Mungkin ini akan membantu Anda.
sumber