Di saya TextViewTableViewCell
, saya punya variabel untuk melacak blok dan metode konfigurasi tempat blok dilewatkan dan ditugaskan.
Ini TextViewTableViewCell
kelas saya :
//
// TextViewTableViewCell.swift
//
import UIKit
class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {
@IBOutlet var textView : UITextView
var onTextViewEditClosure : ((text : String) -> Void)?
func configure(#text: String?, onTextEdit : ((text : String) -> Void)) {
onTextViewEditClosure = onTextEdit
textView.delegate = self
textView.text = text
}
// #pragma mark - Text View Delegate
func textViewDidEndEditing(textView: UITextView!) {
if onTextViewEditClosure {
onTextViewEditClosure!(text: textView.text)
}
}
}
Ketika saya menggunakan metode configure dalam metode saya cellForRowAtIndexPath
, bagaimana cara menggunakan diri lemah di blok yang saya lewati.
Berikut adalah apa yang saya miliki tanpa diri lemah:
let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {(text: String) in
// THIS SELF NEEDS TO BE WEAK
self.body = text
})
cell = bodyCell
PEMBARUAN : Saya mendapat yang berikut untuk bekerja menggunakan [weak self]
:
let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell
myCell.configure(text: body, onTextEdit: {[weak self] (text: String) in
if let strongSelf = self {
strongSelf.body = text
}
})
cell = myCell
Ketika saya melakukan dan [unowned self]
bukannya [weak self]
mengeluarkan if
pernyataan itu, aplikasi mogok. Ada ide tentang bagaimana ini harus bekerja [unowned self]
?
ios
swift
retain-cycle
NatashaTheRobot
sumber
sumber
Jawaban:
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 yang tidak dimiliki] saya akan menebak bahwa diri adalah nol di beberapa titik dalam penutupan itu, itulah sebabnya Anda harus pergi dengan [diri yang lemah] sebagai gantinya.
Saya benar-benar menyukai seluruh bagian dari manual tentang penggunaan kuat , lemah , dan tidak dimiliki dalam penutupan:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
Catatan: Saya menggunakan istilah penutupan alih-alih blok yang merupakan istilah Swift yang lebih baru:
Perbedaan antara blok (Objective C) dan closure (Swift) di ios
sumber
unowned
. Ini tidak sebanding dengan risiko menyebabkan aplikasi Anda mogok.Masukkan
[unowned self]
sebelum(text: String)...
di penutupan Anda. Ini disebut daftar penangkapan dan menempatkan instruksi kepemilikan pada simbol yang ditangkap di penutupan.sumber
** DIedit untuk Swift 4.2:
Seperti yang dikomentari @Koen, swift 4.2 memungkinkan:
PS: Karena saya mendapat suara, saya ingin merekomendasikan bacaan tentang lolos dari penutupan .
Diedit: Seperti yang dikomentari @ tim-vermeulen, Chris Lattner mengatakan pada Jumat 22 Januari 19:51:29 CST 2016, trik ini tidak boleh digunakan pada diri sendiri, jadi tolong jangan gunakan itu. Periksa info penutupan yang tidak lolos dan jawaban daftar tangkap dari @ gbk. **Bagi mereka yang menggunakan [diri lemah] dalam daftar tangkap, perhatikan bahwa diri bisa nol, jadi hal pertama yang saya lakukan adalah memeriksa dengan pernyataan penjaga
Jika Anda bertanya-tanya apa tanda kutip ada di sekitar
self
adalah trik pro untuk menggunakan diri di dalam penutupan tanpa perlu mengubah nama untuk ini , diri lemah atau apa pun.sumber
self
(di backticks). Beri nama itu sesuatu yang lain seperti NonOptionalSelf dan itu akan baik-baik saja.{ [weak self] in guard let self = self else { return }
dapat digunakan tanpa backticks, dan sebenarnya didukung: github.com/apple/swift-evolution/blob/master/proposals/…Gunakan daftar Tangkap
penjelasan tambahan
sumber
EDIT: Referensi ke solusi yang diperbarui oleh LightMan
Lihat solusi LightMan . Sampai sekarang saya menggunakan:
Atau:
Biasanya Anda tidak perlu menentukan tipe parameter jika disimpulkan.
Anda dapat menghilangkan parameter sama sekali jika tidak ada atau jika Anda merujuknya seperti
$0
pada penutupan:Hanya untuk kelengkapan; jika Anda meneruskan penutupan ke suatu fungsi dan parameter tidak
@escaping
, Anda tidak perluweak self
:sumber
Mulai dari 4.2 🔸 yang dapat kita lakukan:
sumber
strongSelf
secara eksplisit menjelaskan arti variabel / efek samping yang bagus jika kodenya lebih panjang. menghargai pendapat Anda, tidak tahu c ++ menggunakan ungkapan seperti itu.guard let self = self else { return }
untuk membuka[weak self]
: github.com/apple/swift-evolution/blob/master/proposals/…Cepat 4.2
https://github.com/apple/swift-evolution/blob/master/proposals/0079-upgrade-self-from-weak-to-strong.md
sumber
Anda dapat menggunakan [diri lemah] atau [diri tidak dimiliki] dalam daftar penangkapan sebelum parameter blok Anda. Daftar penangkapan adalah sintaks opsional.
[unowned self]
bekerja dengan baik di sini karena sel tidak akan pernah menjadi nol. Kalau tidak, Anda bisa menggunakan[weak self]
sumber
Jika Anda menabrak dari yang Anda butuhkan [lemah diri]
Dugaan saya adalah bahwa blok yang Anda buat entah bagaimana masih terhubung.
Buat preparForReuse dan coba bersihkan blok onTextViewEditClosure di dalamnya.
Lihat apakah itu mencegah crash. (Itu hanya tebakan).
sumber
Penutupan dan siklus referensi yang kuat [Tentang]
Seperti yang Anda tahu penutupan Swift dapat menangkap contoh. Ini berarti bahwa Anda dapat menggunakan
self
di dalam penutupan. Terutamaescaping closure
[Tentang] dapat membuatstrong reference cycle
apa. Ngomong-ngomong, Anda harus menggunakanself
di dalam secara eksplisitescaping closure
.Penutupan Swift memiliki
Capture List
fitur yang memungkinkan Anda menghindari situasi seperti itu dan memutus siklus referensi karena tidak memiliki referensi yang kuat untuk instance yang ditangkap. Elemen Capture List adalah sepasangweak
/unowned
dan referensi ke kelas atau variabel.Sebagai contoh
weak
- lebih disukai, gunakan jika memungkinkanunowned
- gunakan ketika Anda yakin bahwa pemilik instance seumur hidup lebih besar dari penutupansumber