In meinem habe TextViewTableViewCell
ich eine Variable, um einen Block zu verfolgen, und eine Konfigurationsmethode, bei der der Block übergeben und zugewiesen wird.
Hier ist meine TextViewTableViewCell
Klasse:
//
// 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)
}
}
}
Wenn ich die configure-Methode in meiner cellForRowAtIndexPath
Methode verwende, wie verwende ich das schwache Selbst in dem Block, den ich übergebe, richtig?
Folgendes habe ich ohne das schwache Selbst:
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
UPDATE : Ich habe Folgendes zum Arbeiten [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
Wenn ich die Anweisung [unowned self]
anstelle von [weak self]
und if
herausnehme, stürzt die App ab. Irgendwelche Ideen, wie das funktionieren soll [unowned self]
?
ios
swift
retain-cycle
NatashaTheRobot
quelle
quelle
Antworten:
Wenn das Selbst im Verschluss gleich Null sein könnte, benutze [schwaches Selbst] .
Wenn das Selbst im Verschluss niemals Null sein wird, verwenden Sie [nicht besessenes Selbst] .
Wenn es abstürzt, wenn Sie [nicht besessenes Selbst] verwenden, würde ich vermuten, dass das Selbst irgendwann in diesem Abschluss gleich Null ist, weshalb Sie stattdessen mit [schwachem Selbst] gehen mussten .
Ich mochte den gesamten Abschnitt aus dem Handbuch über die Verwendung von starken , schwachen und nicht besessenen Verschlüssen sehr:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
Hinweis: Ich habe den Begriff Closure anstelle von Block verwendet, der der neuere Swift-Begriff ist:
Unterschied zwischen Block (Ziel C) und Abschluss (Swift) in ios
quelle
unowned
. Das Risiko eines Absturzes Ihrer App ist es nicht wert.Setzen Sie
[unowned self]
vorher(text: String)...
in Ihren Verschluss. Dies wird als Erfassungsliste bezeichnet und platziert Besitzanweisungen für Symbole, die im Abschluss erfasst wurden.quelle
** BEARBEITET für Swift 4.2:
Wie @Koen kommentierte, erlaubt Swift 4.2:
PS: Da ich einige Up-Votes habe, möchte ich die Lektüre über die Flucht vor Schließungen empfehlen .
BEARBEITET: Wie @ tim-vermeulen kommentiert hat, sagte Chris Lattner am Fri Jan 22 19:51:29 CST 2016, dieser Trick sollte nicht für sich selbst verwendet werden, also bitte nicht verwenden. Überprüfen Sie die Informationen zu nicht entkommenden Schließungen und die Antwort auf die Erfassungsliste von @gbk. **Beachten Sie für diejenigen, die [schwaches Selbst] in der Erfassungsliste verwenden, dass Selbst Null sein kann. Als erstes überprüfe ich dies mit einer Guard-Anweisung
Wenn Sie sich fragen, um welche Anführungszeichen es sich handelt,
self
ist dies ein Pro-Trick, um sich selbst innerhalb des Verschlusses zu verwenden, ohne den Namen in dies , schwaches Selbst oder was auch immer ändern zu müssen .quelle
self
(in Backticks) zu benennen. Nennen Sie es etwas anderes wie nonOptionalSelf und es wird in Ordnung sein.{ [weak self] in guard let self = self else { return }
kann ohne Backticks verwendet werden und wird tatsächlich unterstützt: github.com/apple/swift-evolution/blob/master/proposals/…Verwenden Sie Capture - Liste
zusätzliche Erklärungen
quelle
BEARBEITEN: Verweis auf eine aktualisierte Lösung von LightMan
Siehe LightMans Lösung . Bis jetzt habe ich verwendet:
Oder:
Normalerweise müssen Sie den Parametertyp nicht angeben, wenn er abgeleitet wird.
Sie können den Parameter ganz weglassen, wenn es keinen gibt oder wenn Sie sich wie
$0
im Abschluss darauf beziehen :Nur der Vollständigkeit halber; Wenn Sie den Abschluss an eine Funktion übergeben und der Parameter nicht
@escaping
, benötigen Sie keinweak self
:quelle
Ab Swift 4.2 🔸 können wir:
quelle
strongSelf
erklärt explizit die Variablen Bedeutung / Nebeneffekt, was schön ist, wenn der Code länger ist. Ich schätze Ihre Meinung, wusste nicht, dass C ++ eine solche Formulierung verwendet.guard let self = self else { return }
Folgendes auspacken[weak self]
: github.com/apple/swift-evolution/blob/master/proposals/…Swift 4.2
https://github.com/apple/swift-evolution/blob/master/proposals/0079-upgrade-self-from-weak-to-strong.md
quelle
Sie können [schwaches Selbst] oder [nicht besessenes Selbst] in der Erfassungsliste vor Ihren Parametern des Blocks verwenden. Die Erfassungsliste ist eine optionale Syntax.
[unowned self]
funktioniert hier gut, weil die Zelle niemals Null sein wird. Ansonsten können Sie verwenden[weak self]
quelle
Wenn Sie abstürzen, brauchen Sie wahrscheinlich [schwaches Selbst]
Ich vermute, dass der Block, den Sie erstellen, irgendwie immer noch verkabelt ist.
Erstellen Sie eine prepareForReuse und versuchen Sie, den darin enthaltenen onTextViewEditClosure-Block zu löschen.
Überprüfen Sie, ob dies den Absturz verhindert. (Es ist nur eine Vermutung).
quelle
Abschluss und starke Referenzzyklen [About]
Wie Sie wissen, kann Swifts Schließung die Instanz erfassen. Dies bedeutet, dass Sie
self
in einem Verschluss verwenden können. Insbesondereescaping closure
[About] kann einstrong reference cycle
welche erstellen . Übrigens muss manself
drinnen explizit verwendenescaping closure
.Das schnelle Schließen verfügt über eine
Capture List
Funktion, mit der Sie eine solche Situation vermeiden und einen Referenzzyklus unterbrechen können, da Sie keinen starken Bezug zur erfassten Instanz haben. Das Capture List-Element ist ein Paar vonweak
/unowned
und ein Verweis auf eine Klasse oder Variable.Beispielsweise
weak
- bevorzugter, verwenden Sie es, wenn es möglich istunowned
- Verwenden Sie es, wenn Sie sicher sind, dass die Lebensdauer des Instanzeigners länger ist als die Schließungquelle