Penjelasan tentang penyimpanan yang kuat dan lemah di iOS5

114

Saya baru mengenal pengembangan iOS5 dan menggunakan objektif-c. Saya kesulitan memahami perbedaan antara penyimpanan kuat dan lemah . Saya telah membaca dokumentasi dan pertanyaan SO lainnya, tetapi semuanya terdengar sama bagi saya tanpa wawasan lebih jauh.

Saya membaca dokumentasinya: Transisi Ke ARC - mengacu pada ketentuan iOS4 untuk mempertahankan, menetapkan, dan melepaskan; yang membuatku bingung. Lalu saya melihat ke Open U CS193p, di mana ia membedakan kuat dan lemah:

Kuat : "simpan ini di tumpukan sampai saya tidak menunjuknya lagi"
Lemah : "simpan ini selama orang lain menunjukkannya dengan kuat"

Bukankah kedua definisi tersebut identik = jika pointer tidak lagi menunjuk ke suatu objek, maka bebaskan memori yang menahan objek tersebut? Saya mengerti konsep pointer, heap, alokasi atau deallocation memori - tapi apa perbedaan antara strong dan weak?

KMC
sumber
Model manajemen memori masih relevan meskipun Anda menggunakan ARC. Anda tetap harus memahami penghitungan referensi, hanya saja tidak perlu melakukannya secara manual. Jadi paragraf terakhir Anda adalah permintaan yang tidak masuk akal.
jrturton

Jawaban:

509

Perbedaannya adalah bahwa suatu objek akan dibatalkan alokasinya segera setelah tidak ada petunjuk yang kuat untuk itu. Bahkan jika penunjuk lemah menunjuk ke sana, setelah penunjuk kuat terakhir hilang, objek akan dibatalkan alokasinya, dan semua penunjuk lemah yang tersisa akan dikosongkan.

Mungkin contohnya adalah berurutan.

Bayangkan objek kita adalah seekor anjing, dan bahwa anjing itu ingin melarikan diri (dipindahkan).

Petunjuk yang kuat seperti tali pengikat pada anjing. Selama Anda mengikatkan tali pada anjing, anjing tidak akan lari. Jika lima orang memasang tali kekang pada satu anjing, (lima penunjuk kuat ke satu benda), maka anjing tidak akan lari sampai kelima tali dilepaskan.

Petunjuk yang lemah, di sisi lain, seperti anak kecil yang menunjuk ke arah anjing dan berkata "Lihat! Seekor anjing!" Selama anjing masih terikat, anak-anak kecil masih bisa melihat anjing itu, dan mereka masih akan menunjuknya. Namun, segera setelah semua tali dilepaskan, anjing itu melarikan diri tidak peduli berapa banyak anak kecil yang menunjuknya.

Segera setelah penunjuk kuat terakhir (tali) tidak lagi menunjuk ke suatu objek, objek tersebut akan dibatalkan alokasinya, dan semua penunjuk yang lemah akan dikosongkan.

BJ Homer
sumber
2
Ini didasarkan pada analogi yang diberikan Malcom Crawford di Apple beberapa tahun yang lalu. Tidak tahu dari mana dia mendapatkannya.
BJ Homer
Saya ingat pernah membaca sesuatu yang mirip (pre-arc) di sebuah buku, mengira itu Hillegass, tapi kemudian dia bisa mendapatkannya dari tempat lain ... tapi itu bagus!
jrturton
14
+1 contoh yang sangat baik. Ini adalah turunan dari contoh Hillegass tentang bagaimana tali kekang dipertahankan / dilepaskan, tapi saya suka adaptasi ini untuk yang kuat / lemah.
Dave DeLong
2
@DaveDeLong: Yah, mereka ilegal pada 10.6 dengan ARC. Anda tidak bisa menggunakannya sama sekali. Jadi itu poin yang tidak relevan.
BJ Homer
5
Yang bagus lainnya adalah balon Helium: selama setidaknya satu senar dipegang, itu tidak akan melayang. Analoginya tali / balon juga bagus untuk membuat orang lupa bahwa "kepemilikan" diatur dengan mempertahankan / melepaskan.
Steve Weller
34

Bukankah kedua definisi itu identik.

Benar-benar tidak. Perbedaan utama dalam dua definisi yang Anda tunjukkan adalah "selama orang lain". Itu adalah "orang lain" yang penting.

Pertimbangkan hal berikut:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Sekarang kita punya dua petunjuk <some_object>, satu kuat dan satu lemah. Jika kita mengatur strongObjectuntuk nilsuka begitu:

strongObject = nil;

Kemudian jika Anda mengikuti aturan yang Anda gariskan maka Anda akan bertanya pada diri sendiri pertanyaan-pertanyaan ini:

  1. Kuat: "simpan ini di tumpukan sampai saya tidak menunjukkannya lagi"

    strongObjecttidak menunjuk <some_object>lagi. Jadi kita tidak perlu menyimpannya.

  2. Lemah: "simpan ini selama orang lain menunjukkannya dengan kuat"

    weakObjectmasih menunjuk ke <some_object>. Tetapi karena tidak ada orang lain yang menunjuk padanya, aturan ini juga berarti bahwa kita tidak perlu menyimpannya.

Hasilnya adalah yang <some_object>dibatalkan alokasinya dan jika runtime Anda mendukungnya (Lion dan iOS 5 ke atas) maka weakObjectsecara otomatis akan diatur ke nil.

Sekarang perhatikan apa yang terjadi jika kita menetapkan weakObjectuntuk nilsuka begitu:

weakObject = nil;

Kemudian jika Anda mengikuti aturan yang Anda gariskan maka Anda akan bertanya pada diri sendiri pertanyaan-pertanyaan ini:

  1. Kuat: "simpan ini di tumpukan sampai saya tidak menunjukkannya lagi"

    strongObjectmenunjuk ke <some_object>. Jadi kita perlu menyimpannya.

  2. Lemah: "simpan ini selama orang lain menunjukkannya dengan kuat"

    weakObjecttidak menunjuk ke <some_object>.

Hasilnya adalah bahwa <some_object>ini tidak deallocated, tetapi weakObjectakan menjadi nilpointer.

[Perhatikan bahwa semua yang berasumsi <some_object>tidak ditunjukkan oleh referensi kuat lain di tempat lain / cara lain untuk "ditahan"]

mattjgalloway
sumber
1
Jadi perbedaan utama antara kuat dan lemah adalah bahwa deallokasi objek yang diarahkan dengan kuat akan secara otomatis menghapus semua poin lemah terkait. Dan untuk penunjuk yang lemah untuk menunjuk ke sesuatu, selalu ada penunjuk yang kuat. Jika demikian, objek aplikasi utama harus diarahkan dengan kuat?
KMC
Untuk penunjuk yang lemah untuk menunjuk ke sesuatu yang valid maka ya harus ada penunjuk yang kuat. Tambahkan ke fakta bahwa iOS 5 dan Lion mendukung pengisian otomatis referensi lemah dan Anda mendapatkan apa yang Anda katakan. Runtime iOS 4 tidak mendukung itu. "Objek aplikasi utama" Saya berasumsi bahwa yang Anda maksud adalah UIApplicationobjek? Itu akan sangat direferensikan oleh cara kerja bagian dalam UIKit- tetapi Anda tidak perlu khawatir tentang itu.
mattjgalloway
Saya rasa Anda dapat menggunakan kata seperti "strongObjectPointer" daripada "strongObject". Jadi orang baru dalam pemrograman akan memiliki arti yang lebih baik. Tangkapan bagus di @BJ Homer memposting Mr. Matt. Menarik :)
Vijay-Apple-Dev.blogspot.com
2

Kuat

  1. Menciptakan kepemilikan antara properti dan nilai yang diberikan.
  2. Ini adalah default untuk properti objek di ARC sehingga tidak membiarkan Anda mengkhawatirkan jumlah referensi dan melepaskan referensi secara otomatis.
  3. Ini adalah pengganti retensi. Kami menggunakan jika dan hanya jika kami perlu menggunakan sebagai retensi.

Lemah

  1. Menciptakan non-kepemilikan antara properti dan nilai yang ditetapkan.
  2. Kuat digunakan pada objek induk dan lemah digunakan pada objek anak ketika induk dilepaskan maka referensi objek anak juga disetel ke nil
  3. Ini membantu untuk mencegah siklus penahanan.
  4. Itu tidak melindungi objek yang direferensikan saat dikumpulkan oleh pengumpul sampah.
  5. Lemah pada dasarnya ditugaskan, properti tidak dipertahankan.
Shashi3456643
sumber
Perlu disebutkan di sini apa siklus penahanan biasanya. Kami memiliki dua objek: objek A dan objek B. Objek A memiliki referensi yang kuat ke objek B dan objek B memiliki referensi yang kuat ke objek A. Tidak ada lagi yang memiliki referensi kuat ke objek A atau B.
boro
2

Contoh lain: Mahasiswa adalah seorang Object, diharapkan bahwa ia dapat lulus ( deallocate) selama ia menyelesaikan semua mata kuliah inti ( strong pointers), tidak peduli ia mengambil mata kuliah pilihan ( weak pointers). Dengan kata lain: penunjuk yang kuat adalah satu-satunya faktor pelepasan alokasi itu Object.

RobotCharlie
sumber
1

Tidak, mereka tidak identik tetapi sangat berbeda. Gunakan kuat hanya jika Anda perlu mempertahankan objek. Anda menggunakan weak pada kasus lain, dengan de keuntungannya Anda dapat mengetahui apakah objek telah dihapus dari heap karena tidak ada yang menahannya.

Gabriel
sumber
1

Saya tahu saya agak terlambat ke pesta ini, tetapi menurut saya penting untuk mengacaukan masalah ini dengan menunjukkan bahwa arti "model memori yang kuat dan lemah" bergantung pada apakah Anda berbicara tentang perangkat lunak atau perangkat keras.

Untuk perangkat keras, lemah atau kuat menunjukkan apakah ada dukungan untuk konsistensi urutan.

[SC berarti bahwa] ... hasil dari setiap eksekusi sama seperti jika operasi semua prosesor dijalankan dalam beberapa urutan berurutan, dan operasi masing-masing prosesor muncul dalam urutan ini dalam urutan yang ditentukan oleh programnya. - Lamport, 1979

WTF apakah itu ada hubungannya dengan memori? Ini menyiratkan bahwa penulisan ke variabel oleh prosesor yang berbeda harus dilihat dalam urutan yang sama oleh semua prosesor. Dalam perangkat keras dengan model yang kuat, ini dijamin. Pada perangkat keras dengan model yang lemah, sebenarnya tidak.

Jawaban yang ada menafsirkan pertanyaan hanya dalam istilah model memori perangkat lunak. Perangkat keras tidak relevan dengan pemrograman. Pertanyaan ini menyebutkan iOS, yang biasanya berjalan pada prosesor Arm7. Arm7 memiliki model memori yang lemah. Untuk programmer yang terbiasa dengan prosesor dengan model yang kuat - kita semua karena x86 dan x64 memiliki model yang kuat - ini adalah jebakan yang buruk. Menggunakan bool untuk memberi sinyal utas lain untuk keluar berfungsi dengan baik dalam model yang kuat. Kode yang sama pada Arm tidak berfungsi sama sekali kecuali Anda menandai bendera tersebut mudah menguap, dan bahkan kemudian tidak menentu.

Meskipun benar bahwa Arm8 + mengubah ini sepenuhnya dengan dukungan eksplisit untuk perolehan / rilis, perangkat lunak lawas tidak menggunakan dukungan ini. Perangkat lunak lawas mencakup ketiga OS ponsel dan semua yang berjalan di atasnya, serta kompiler dan pustaka hingga diperbarui.

Untuk pemeriksaan lebih lanjut tentang topik ini, saya merujuk Anda ke Herb Sutter yang tak ada bandingannya .

Peter Wone
sumber