Saya berselancar melalui blog indah yang dikelola oleh Scott Stevenson, dan saya mencoba memahami konsep Objective-C yang mendasar dalam menugaskan delegasi properti 'assign' vs 'retain'. Catatan, keduanya sama di lingkungan pengumpulan sampah. Saya sebagian besar peduli dengan lingkungan berbasis non-GC (misalnya: iPhone).
Langsung dari blog Scott:
"Kata kunci yang ditetapkan akan menghasilkan setter yang memberikan nilai ke variabel instan secara langsung, daripada menyalin atau mempertahankannya. Ini terbaik untuk tipe primitif seperti NSInteger dan CGFloat, atau objek yang tidak Anda miliki secara langsung, seperti delegasi."
Apa artinya Anda tidak secara langsung memiliki objek delegasi? Saya biasanya mempertahankan delegasi saya, karena jika saya tidak ingin mereka pergi ke jurang, mempertahankan itu akan mengurusnya untuk saya. Saya biasanya abstrak UITableViewController jauh dari masing-masing dataSource dan mendelegasikan juga. Saya juga mempertahankan objek tertentu. Saya ingin memastikan itu tidak pernah hilang sehingga UITableView saya selalu memiliki delegasinya.
Dapatkah seseorang menjelaskan lebih lanjut di mana / mengapa saya salah, jadi saya bisa memahami paradigma umum ini dalam pemrograman Objective-C 2.0 menggunakan properti assign pada delegasi alih-alih mempertahankan?
Terima kasih!
sumber
Jawaban:
Alasan Anda menghindari mempertahankan delegasi adalah karena Anda harus menghindari siklus penyimpanan:
A menciptakan B A menetapkan dirinya sebagai delegasi B… A dilepaskan oleh pemiliknya
Jika B mempertahankan A, A tidak akan dilepaskan, karena B memiliki A, sehingga dealloc A tidak akan pernah dipanggil, menyebabkan A dan B bocor.
Anda tidak perlu khawatir tentang A pergi karena memiliki B dan dengan demikian menghilangkannya dalam dealloc.
sumber
weak
artinya? Pertanyaannya adalah mengapa menggunakanassign
bukanweak
?assign
bukanretain
. Pertanyaannya lebih tua dari ARC;weak
danstrong
(yang terakhir identik denganretain
) tidak ada sampai ARC diperkenalkan. Anda harus menanyakan pertanyaan Anda tentangweak
vs.assign
secara terpisah.Karena objek yang mengirim pesan delegasi tidak memiliki delegasi.
Sering kali, itu sebaliknya, seperti ketika controller menetapkan dirinya sebagai delegasi dari view atau window: controller memiliki view / window, jadi jika view / window memiliki delegate, kedua objek akan saling memiliki. Ini, tentu saja, adalah siklus penahan, mirip dengan kebocoran dengan konsekuensi yang sama (benda yang seharusnya mati tetap hidup).
Di lain waktu, objeknya adalah rekan-rekan: tidak ada yang memiliki yang lain, mungkin karena keduanya dimiliki oleh objek ketiga yang sama.
Either way, objek dengan delegasi tidak boleh mempertahankan delegasinya.
(Ngomong-ngomong, setidaknya ada satu pengecualian. Aku tidak ingat apa itu, dan kurasa tidak ada alasan bagus untuk itu.)
Tambahan (ditambahkan 2012-05-19): Di bawah ARC, Anda harus menggunakan
weak
bukanassign
. Referensi yang lemah diaturnil
secara otomatis ketika objek mati, menghilangkan kemungkinan bahwa objek delegasi akhirnya mengirim pesan ke delegasi mati.Jika Anda menjauh dari ARC karena suatu alasan, setidaknya ubah
assign
properti yang menunjuk ke objekunsafe_unretained
, yang secara eksplisit menyatakan bahwa ini adalah referensi yang tidak dibatasi tetapi tidak memusatkan perhatian pada suatu objek.assign
tetap sesuai untuk nilai-nilai non-objek di bawah ARC dan MRC.sumber
NSURLConnection
mempertahankan delegasinya.weak
, tetapi itu tidak menjawab pertanyaan asli: Mengapa Apple menggunakanassign
bukanweak
?assign
alih-alih dipertahankan ";weak
tidak ada saat ditanya. Pertanyaan Anda berbeda, yang harus Anda tanyakan secara terpisah. Saya akan dengan senang hati menjawabnya.Perhatikan bahwa ketika Anda memiliki delegasi yang ditugaskan, itu membuatnya sangat penting untuk selalu menetapkan nilai delegasi itu menjadi nol setiap kali objek akan dideallocated - jadi objek harus selalu berhati-hati untuk mencari referensi delegasi di dealloc jika belum melakukannya di tempat lain.
sumber
Salah satu alasan di balik itu adalah untuk menghindari siklus mempertahankan. Hanya untuk menghindari skenario di mana A dan B keduanya saling referensi satu sama lain dan tidak ada yang dilepaskan dari memori.
Acutally menetapkan yang terbaik untuk tipe primitif seperti NSInteger dan CGFloat, atau benda Anda tidak langsung sendiri, seperti delegasi.
sumber