Dans my TextViewTableViewCell
, j'ai une variable pour garder une trace d'un bloc et une méthode de configuration où le bloc est passé et attribué.
Voici ma TextViewTableViewCell
classe:
//
// 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)
}
}
}
Quand j'utilise la méthode configure dans ma cellForRowAtIndexPath
méthode, comment utiliser correctement le self faible dans le bloc que je passe.
Voici ce que j'ai sans le self faible:
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
MISE À JOUR : J'ai fait fonctionner les éléments suivants en utilisant [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
Lorsque je fais [unowned self]
au lieu de [weak self]
et que je retire la if
déclaration, l'application se bloque. Des idées sur la façon dont cela devrait fonctionner [unowned self]
?
ios
swift
retain-cycle
NatashaTheRobot
la source
la source
Réponses:
Si le soi pouvait être nul dans la fermeture, utilisez [soi faible] .
Si le soi ne sera jamais nul dans la fermeture, utilisez [soi sans propriétaire] .
Si ça plante quand vous utilisez [soi sans propriétaire], je suppose que le soi est nul à un moment donné de cette fermeture, c'est pourquoi vous avez dû opter pour [le moi faible] à la place.
J'ai vraiment aimé toute la section du manuel sur l'utilisation de fermetures fortes , faibles et inconnues :
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
Remarque: j'ai utilisé le terme fermeture au lieu de bloc qui est le nouveau terme Swift:
Différence entre le bloc (Objectif C) et la fermeture (Swift) dans iOS
la source
unowned
. Cela ne vaut pas le risque de faire planter votre application.Mettez
[unowned self]
avant(text: String)...
dans votre fermeture. Cela s'appelle une liste de capture et place des instructions de propriété sur les symboles capturés dans la fermeture.la source
** MODIFIÉ pour Swift 4.2:
Comme @Koen l'a commenté, swift 4.2 permet:
PS: Étant donné que j'ai des votes positifs, je voudrais recommander la lecture sur les fermetures .
EDITED: Comme @ tim-vermeulen l'a commenté, Chris Lattner l'a déclaré le vendredi 22 janvier à 19:51:29 CST 2016, cette astuce ne doit pas être utilisée sur soi-même, alors ne l'utilisez pas. Vérifiez les informations sur les fermetures qui ne s'échappent pas et la réponse de la liste de capture de @gbk. **Pour ceux qui utilisent [self faible] dans la liste de capture, notez que self peut être nul, donc la première chose que je fais est de vérifier cela avec une déclaration de garde
Si vous vous demandez ce que sont les guillemets,
self
c'est une astuce professionnelle pour utiliser self à l'intérieur de la fermeture sans avoir besoin de changer le nom en ceci , lowSelf ou autre.la source
self
(dans les backticks). Nommez-le autre chose comme nonOptionalSelf et tout ira bien.{ [weak self] in guard let self = self else { return }
peut être utilisé sans backticks, et est en fait supporté: github.com/apple/swift-evolution/blob/master/proposalsUtiliser la liste de capture
explications supplémentaires
la source
EDIT: Référence à une solution mise à jour par LightMan
Voir la solution de LightMan . Jusqu'à présent, j'utilisais:
Ou:
En général, vous n'avez pas besoin de spécifier le type de paramètre s'il est déduit.
Vous pouvez omettre complètement le paramètre s'il n'y en a pas ou si vous vous y référez comme
$0
dans la fermeture:Juste pour être complet; si vous passez la fermeture à une fonction et que le paramètre ne l'est pas
@escaping
, vous n'avez pas besoin d'unweak self
:la source
Depuis Swift 4.2 🔸, nous pouvons faire:
la source
strongSelf
explique explicitement les variables signification / effet secondaire, ce qui est bien si le code est de nature plus longue. apprécier votre avis cependant, ne savais pas que c ++ utilisé une telle formulation.guard let self = self else { return }
pour déballer[weak self]
: github.com/apple/swift-evolution/blob/master/proposalsSwift 4.2
https://github.com/apple/swift-evolution/blob/master/proposals/0079-upgrade-self-from-weak-to-strong.md
la source
Vous pouvez utiliser [soi faible] ou [soi sans propriétaire] dans la liste de capture avant vos paramètres du bloc. La liste de capture est une syntaxe facultative.
[unowned self]
fonctionne bien ici car la cellule ne sera jamais nulle. Sinon, vous pouvez utiliser[weak self]
la source
Si vous vous écrasez, vous avez probablement besoin de [moi faible]
Je suppose que le bloc que vous créez est en quelque sorte toujours câblé.
Créez un prepareForReuse et essayez d'effacer le bloc onTextViewEditClosure à l'intérieur.
Voyez si cela empêche le crash. (C'est juste une supposition).
la source
Clôture et cycles de référence solides [À propos]
Comme vous le savez, la fermeture de Swift peut capturer l'instance. Cela signifie que vous pouvez utiliser à l'
self
intérieur d'une fermeture. Surtoutescaping closure
[About] peut créer unstrong reference cycle
qui. Au fait, vous devez explicitement utiliserself
insideescaping closure
.La fermeture rapide a une
Capture List
fonction qui vous permet d'éviter une telle situation et de rompre un cycle de référence car vous n'avez pas de référence forte à l'instance capturée. L'élément Capture List est une paire deweak
/unowned
et une référence à une classe ou une variable.Par exemple
weak
- plus préférable, utilisez-le quand c'est possibleunowned
- utilisez-le lorsque vous êtes sûr que la durée de vie du propriétaire de l'instance est supérieure à la fermeturela source