Swift memiliki:
- Referensi yang kuat
- Referensi yang lemah
- Referensi yang Tidak Dimiliki
Bagaimana perbedaan referensi yang tidak dimiliki berbeda dengan referensi yang lemah?
Kapan aman menggunakan referensi yang tidak dimiliki?
Apakah referensi yang tidak diketahui memiliki risiko keamanan seperti pointer yang menggantung di C / C ++?
unowned
untuk kelas yang kami kontrol, untuk kelas Apple, gunakanweak
karena kami tidak dapat memastikan dengan pasti apa yang dilakukannyaJawaban:
Keduanya
weak
danunowned
referensi tidak membuatstrong
penangguhan pada objek yang dirujuk (alias mereka tidak menambah jumlah retain untuk mencegah ARC dari deallocating objek yang dirujuk).Tapi mengapa dua kata kunci? Perbedaan ini berkaitan dengan fakta bahwa
Optional
tipe adalah bawaan dalam bahasa Swift. Singkat cerita tentang mereka: tipe opsional menawarkan keamanan memori (ini bekerja dengan baik dengan aturan konstruktor Swift - yang ketat untuk memberikan manfaat ini).Sebuah
weak
referensi memungkinkan kemungkinan untuk menjadinil
(ini terjadi secara otomatis ketika objek direferensikan deallocated), oleh karena itu jenis properti Anda harus opsional - sehingga Anda, sebagai programmer, wajib untuk memeriksa sebelum Anda menggunakannya (pada dasarnya kompiler memaksa Anda, sebanyak mungkin, untuk menulis kode aman).Sebuah
unowned
mengandaikan referensi bahwa itu tidak akan pernah menjadinil
selama masa pakai baterai. Referensi yang tidak dimiliki harus ditetapkan selama inisialisasi - ini berarti bahwa referensi akan didefinisikan sebagai jenis non-opsional yang dapat digunakan dengan aman tanpa pemeriksaan. Jika entah bagaimana objek yang dirujuk tidak dapat dialokasikan, maka aplikasi akan macet ketika referensi yang tidak dimiliki akan digunakan.Dari dokumen Apple :
Dalam dokumen, ada beberapa contoh yang membahas mempertahankan siklus dan cara memutusnya. Semua contoh ini diekstraksi dari dokumen .
Contoh
weak
kata kunci:Dan sekarang, untuk beberapa seni ASCII (Anda harus melihat dokumen - mereka memiliki diagram cantik):
Contoh
Person
danApartment
menunjukkan situasi di mana dua properti, keduanya diizinkan nol, memiliki potensi untuk menyebabkan siklus referensi yang kuat. Skenario ini paling baik diselesaikan dengan referensi yang lemah. Kedua entitas dapat eksis tanpa memiliki ketergantungan yang ketat pada yang lain.Contoh
unowned
kata kunci:Dalam contoh ini, a
Customer
mungkin atau mungkin tidak memilikiCreditCard
, tetapi aCreditCard
akan selalu dikaitkan dengan aCustomer
. Untuk mewakili ini,Customer
kelas memilikicard
properti opsional , tetapiCreditCard
kelas memiliki properti non-opsional (dan tidak dimiliki)customer
.Contoh
Customer
danCreditCard
memperlihatkan situasi di mana satu properti yang diizinkan menjadi nol dan properti lain yang tidak dapat nol memiliki potensi untuk menyebabkan siklus referensi yang kuat. Skenario ini paling baik diselesaikan dengan referensi yang tidak dimiliki.Catatan dari Apple:
Ada juga skenario ketiga ketika kedua properti harus selalu memiliki nilai, dan properti tidak boleh nihil setelah inisialisasi selesai.
Dan ada juga skenario siklus mempertahankan klasik yang harus dihindari ketika bekerja dengan penutupan.
Untuk ini, saya mendorong Anda untuk mengunjungi dokumen Apple , atau membaca buku .
sumber
weak var Person?
vsvar Person?
?Q1. Apa perbedaan antara “Referensi yang tidak dimiliki” dengan “Referensi yang Lemah”?
Referensi yang lemah:
Referensi Tidak Dimiliki:
Kapan Harus Menggunakan Masing-masing:
Q2. Kapan aman menggunakan "referensi tidak dimiliki"?
Seperti dikutip di atas, referensi yang tidak dimiliki diasumsikan selalu memiliki nilai. Jadi, Anda hanya boleh menggunakannya ketika Anda yakin bahwa referensi tidak akan pernah nol. Apple Documents mengilustrasikan kasus penggunaan untuk referensi yang tidak dimiliki melalui contoh berikut.
Misalkan kita memiliki dua kelas
Customer
danCreditCard
. Pelanggan dapat ada tanpa kartu kredit, tetapi kartu kredit tidak akan ada tanpa pelanggan, yaitu dapat diasumsikan bahwa kartu kredit akan selalu memiliki pelanggan. Jadi, mereka harus memiliki hubungan sebagai berikut:Q3. Apakah "referensi yang tidak dimiliki" merujuk risiko keamanan seperti "pointer menggantung" di C / C ++
Saya kira tidak.
Karena referensi yang tidak dimiliki hanyalah referensi lemah yang dijamin memiliki nilai, itu tidak boleh menjadi risiko keamanan dengan cara apa pun. Namun, jika Anda mencoba mengakses referensi yang tidak dimiliki setelah instansinya dibatalkan, Anda akan memicu kesalahan runtime, dan aplikasi akan macet.
Itulah satu-satunya risiko yang saya lihat.
Tautan ke Apple Documents
sumber
unowned
untuk properti orangtua di kelas anak. lemah adalah sebaliknya. Penjelasan bagus @myxtic!unowned
referensi hanyaweak
referensi yang dijamin memiliki nilai!Jika diri bisa nol dalam penutupan gunakan [diri lemah] .
Jika diri tidak akan pernah nol dalam penutupan gunakan [diri yang tidak dimiliki] .
Jika crash ketika Anda menggunakan [diri tidak dimiliki] maka diri mungkin nihil di beberapa titik dalam penutupan itu dan Anda mungkin perlu menggunakan [diri lemah] sebagai gantinya.
Lihatlah contoh penggunaan kuat , lemah , dan tidak dimiliki dalam penutupan:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
sumber
self
nihil?Ekstrak dari tautan
Beberapa poin penutup
sumber
Keduanya
weak
danunowned
referensi tidak akan memengaruhi jumlah referensi objek. Tetapi referensi yang lemah akan selalu bersifat opsional yaitu bisa nol, sedangkanunowned
referensi tidak pernah bisa nol sehingga mereka tidak akan pernah opsional. Saat menggunakan referensi opsional, Anda harus selalu menangani kemungkinan objek menjadi nol. Dalam hal referensi yang tidak dimiliki, Anda harus memastikan bahwa objek tidak pernah nol. Menggunakan referensi yang tidak dimiliki untuk objek nil akan sama dengan membuka secara paksa opsi yang nil.Yang mengatakan itu aman untuk menggunakan referensi yang tidak dimiliki di mana Anda yakin bahwa umur objek lebih dari referensi. Jika bukan itu masalahnya, lebih baik menggunakan referensi yang lemah sebagai gantinya.
Adapun bagian ketiga dari pertanyaan, saya tidak berpikir referensi yang tidak dimiliki mirip dengan pointer menggantung. Ketika kita berbicara tentang jumlah referensi, kita biasanya merujuk pada jumlah referensi yang kuat dari objek. Demikian pula swift mempertahankan jumlah referensi yang tidak dimiliki dan jumlah referensi yang lemah untuk objek (referensi lemah menunjuk ke sesuatu yang disebut "tabel samping" daripada objek itu sendiri). Ketika jumlah referensi yang kuat mencapai nol, objek akan diinisialisasi, tetapi itu tidak dapat dibatalkan alokasinya jika jumlah referensi yang tidak dimiliki lebih dari nol.
Sekarang pointer menggantung adalah sesuatu yang menunjuk ke lokasi memori yang telah di-deallocated. Tetapi dengan cepat karena memori hanya dapat dideallocating selama ada referensi yang tidak dimiliki objek, itu tidak dapat menyebabkan pointer menggantung.
Ada banyak artikel yang membahas manajemen memori cepat secara lebih rinci. Ini satu.
sumber
Referensi yang tidak dimiliki adalah sejenis referensi lemah yang digunakan dalam kasus hubungan Same-Seumur Hidup antara dua objek, ketika sebuah objek seharusnya hanya dimiliki oleh satu objek lain. Ini adalah cara untuk membuat pengikatan abadi antara objek dan salah satu propertinya.
Dalam contoh yang diberikan dalam video WWDC cepat antara, seseorang memiliki kartu kredit, dan kartu kredit hanya dapat memiliki satu pemegang. Pada kartu kredit, orang tersebut tidak boleh menjadi properti opsional, karena Anda tidak ingin memiliki kartu kredit yang beredar hanya dengan satu pemilik. Anda dapat memutus siklus ini dengan menjadikan properti pemegang kredit sebagai referensi lemah, tetapi itu juga mengharuskan Anda untuk menjadikannya opsional dan juga variabel (tidak seperti konstanta). Referensi yang tidak diketahui dalam hal ini berarti bahwa meskipun CreditCard tidak memiliki kepemilikan saham pada Seseorang, nyawanya tergantung padanya.
sumber
Gunakan
unowned
saat Anda yakinself
tidak akan pernah bisanil
sampai di titik yang Anda aksesself
pada saat itu.Contoh (Anda tentu saja dapat menambahkan target langsung dari
MyViewController
, tetapi sekali lagi, ini adalah contoh sederhana) .:Gunakan
weak
saat ada kemungkinanself
bisanil
pada titik yang Anda aksesself
.Contoh:
Kekurangan dari
unowned
:Kekurangan dari
weak
:Jika Anda tidak yakin, gunakan
weak
. Tunggu , maksud saya tanyakan di sini di StackOverflow apa yang harus Anda lakukan dalam kasus Anda! Menggunakan lemah setiap saat ketika Anda seharusnya tidak hanya membingungkan bagi Anda dan pembaca kode Anda.sumber