Saya ingin tahu dalam situasi apa yang Anda gunakan -retainCount
sejauh ini, dan pada akhirnya masalah yang dapat terjadi saat menggunakannya.
Terima kasih.
Saya ingin tahu dalam situasi apa yang Anda gunakan -retainCount
sejauh ini, dan pada akhirnya masalah yang dapat terjadi saat menggunakannya.
Terima kasih.
Jawaban:
Anda tidak boleh menggunakan -retainCount
, karena tidak pernah memberi tahu Anda sesuatu yang berguna. Implementasi kerangka kerja Foundation dan AppKit / UIKit tidak jelas; Anda tidak tahu apa yang dipertahankan, mengapa itu dipertahankan, siapa yang mempertahankannya, kapan itu dipertahankan, dan seterusnya.
Sebagai contoh:
[NSNumber numberWithInt:1]
akan memiliki retainCount
1. Tidak. Ini 2.@"Foo"
akan memiliki retainCount
1. Tidak. Ini 1152921504606846975.[NSString stringWithString:@"Foo"]
akan memiliki retainCount
1. Tidak. Sekali lagi, ini 1152921504606846975.Pada dasarnya, karena apa pun dapat mempertahankan objek (dan karenanya mengubahnya retainCount
), dan karena Anda tidak memiliki sumber untuk sebagian besar kode yang menjalankan aplikasi, objek menjadi retainCount
tidak berarti.
Jika Anda mencoba melacak mengapa sebuah objek tidak dibatalkan alokasinya, gunakan alat Kebocoran di Instrumen. Jika Anda mencoba melacak mengapa suatu objek dibatalkan alokasinya terlalu cepat, gunakan alat Zombies di Instrumen.
Tapi jangan gunakan -retainCount
. Itu adalah metode yang benar-benar tidak berguna.
edit
Harap semua orang membuka http://bugreport.apple.com dan meminta agar -retainCount
tidak digunakan lagi. Semakin banyak orang yang memintanya, semakin baik.
edit # 2
Sebagai pemutakhiran, [NSNumber numberWithInt:1]
sekarang memiliki retainCount
9223372036854775807. Jika kode Anda mengharapkannya menjadi 2, kode Anda sekarang telah rusak.
- (NSUInteger)retainCount{return NSUIntegerMax;}
.
retainCount
.
Sungguh. Jangan lakukan itu.
Cukup ikuti Panduan Manajemen Memori dan hanya sebarkan apa yang Anda alloc
, new
atau copy
(atau apa pun yang Anda minta retain
pada awalnya).
@bbum mengatakan yang terbaik di sini di SO , dan bahkan lebih detail di blognya .
-retainCount
dapat diperoleh (dengan lebih detail) dari Instrumen dan alatnya.
retain
, retain
, retain
, autorelease,
autorelease, autorelease
bisa menjadi hasil yang valid sempurna lewat sebuah objek melalui UIKit API, misalnya.
Objek autoreleased adalah salah satu kasus di mana pemeriksaan -retainCount tidak informatif dan berpotensi menyesatkan. Jumlah retensi tidak memberi tahu Anda tentang berapa kali -autorelease dipanggil pada suatu objek dan oleh karena itu berapa kali akan dirilis ketika kumpulan autorelease saat ini habis.
Saya tidak menemukan retainCounts sangat berguna ketika diperiksa menggunakan 'Instrumen'.
Dengan menggunakan alat 'alokasi', pastikan 'Rekam jumlah referensi' diaktifkan dan Anda dapat masuk ke objek apa pun dan melihat riwayat terus menghitungnya.
Dengan memasangkan allocs dan rilis, Anda bisa mendapatkan gambaran yang baik tentang apa yang sedang terjadi dan sering kali menyelesaikan kasus-kasus sulit di mana sesuatu tidak dirilis.
Ini tidak pernah mengecewakan saya - termasuk menemukan bug di rilis beta awal iOS.
Lihatlah dokumentasi Apple di NSObject, itu cukup banyak mencakup pertanyaan Anda: NSObject mempertahankanCount
Singkatnya, retretCount mungkin tidak berguna bagi Anda kecuali Anda telah menerapkan sistem penghitungan referensi Anda sendiri (dan saya hampir dapat menjamin Anda tidak akan melakukannya).
Dalam kata-kata Apple sendiri, retensiCount "biasanya tidak ada nilainya dalam men-debug masalah manajemen memori".
Tentu saja Anda tidak boleh menggunakan metode retensiCount dalam kode Anda, karena arti nilainya bergantung pada berapa banyak autorelease yang telah diterapkan ke objek dan itu adalah sesuatu yang tidak dapat Anda prediksi. Namun ini sangat berguna untuk debugging - terutama saat Anda mencari kebocoran memori dalam kode yang memanggil metode objek Appkit di luar loop event utama - dan ini tidak boleh dihentikan.
Dalam upaya Anda untuk menyampaikan maksud Anda, Anda secara serius melebih-lebihkan sifat nilai yang tidak dapat dipahami. Memang benar bahwa ini tidak selalu merupakan hitungan referensi. Ada beberapa nilai khusus yang digunakan untuk flag, misalnya untuk menunjukkan bahwa objek tidak boleh dibatalkan alokasinya. Angka seperti 1152921504606846975 terlihat sangat misterius sampai Anda menuliskannya dalam hex dan mendapatkan 0xfffffffffffffff. Dan 9223372036854775807 adalah 0x7fffffffffffffff dalam hex. Dan sebenarnya tidak terlalu mengherankan bahwa seseorang akan memilih untuk menggunakan nilai seperti ini sebagai flag, mengingat akan memakan waktu hampir 3000 tahun untuk mendapatkan retretCount setinggi angka yang lebih besar, dengan asumsi Anda menaikkan retretCount 100.000.000 kali per detik.
Masalah apa yang bisa Anda dapatkan dari menggunakannya? Yang dilakukannya hanyalah mengembalikan jumlah retensi objek. Saya tidak pernah menyebutnya dan tidak dapat memikirkan alasan apa pun yang saya lakukan. Saya telah menimpanya dalam jumlah tunggal untuk memastikan alokasi tersebut tidak dibatalkan.
retainCount
untuk manajemen memori.
Anda tidak perlu khawatir tentang kebocoran memori sampai aplikasi Anda aktif dan berjalan dan melakukan sesuatu yang berguna.
Setelah itu, jalankan Instrumen dan gunakan aplikasi dan lihat apakah kebocoran memori benar-benar terjadi. Dalam kebanyakan kasus, Anda membuat objek sendiri (sehingga Anda memilikinya) dan lupa melepaskannya setelah selesai.
Jangan mencoba dan mengoptimalkan kode Anda saat Anda menulisnya, tebakan Anda tentang apa yang mungkin membocorkan memori atau memakan waktu terlalu lama seringkali salah ketika Anda benar-benar menggunakan aplikasi secara normal.
Cobalah dan tulis kode yang benar, misalnya jika Anda membuat objek menggunakan alok dan semacamnya, maka pastikan Anda melepaskannya dengan benar.
Anda tidak boleh menggunakannya dalam kode Anda, tetapi itu pasti bisa membantu saat debugging
-retainCount
.