[Swift] Liste de capture

Quel est ce message?

Ceci est une traduction originale de Contenu du document officiel pour la liste de capture dans la programmation Swift.

environnement

macOS 10.15.7 Xcode 12.1 Swift 5.3

Qu'est-ce qu'une liste de capture?

Par défaut, l'expression de fermeture capture "les constantes et les variables dans sa portée environnante" avec une ** référence forte **. La liste de capture vous donne un contrôle explicite sur la façon dont la fermeture capture la valeur.

La liste de capture est décrite comme "une liste séparée par des virgules entre crochets" avant la liste de paramètres. Lorsque vous utilisez une liste de capture, utilisez toujours le mot-clé ʻin`, même si vous omettez le nom du paramètre, le paramètre et les types de retour.

{ [value1, value2, ...] in STATEMENT }

Les entrées de la liste de capture sont initialisées lors de la création de la fermeture. Les constantes de chaque entrée de la liste de capture sont initialisées à la valeur de "Constantes ou variables de même nom dans la portée environnante". Par exemple, dans le code ci-dessous, «a» est inclus dans la liste de capture, mais «b» ne l'est pas.

python


var a = 0
var b = 0
let closure = { [a] in    //a est initialisé à 0
    print(a, b)           //Changer un hors du périmètre n'a aucun effet
}

a = 10                    //Ce changement n'affecte pas un dans la liste de capture
b = 10
closure()
// Prints "0 10"

Le ʻa dans la portée est initialisé avec la "valeur ʻa hors de la portée" lorsque la fermeture est créée, mais ces valeurs ne sont pas spécifiquement liées. C'est-à-dire que changer un «a» hors de portée n'affecte pas un «a» dans la portée, et un changement en un «a» plus proche n'affecte pas un «a» hors de portée. En revanche, il n'y a qu'une seule variable nommée b en dehors de la portée, de sorte que le changement affecte à la fois l'intérieur et l'extérieur de la fermeture.

Cependant, cette distinction n'est pas faite si la variable capturée était des «données de type référence». Par exemple, dans le code ci-dessous, il y a deux «x» dans les «variables hors de portée» et les «constantes dans la portée», mais les deux font référence au même objet car ce sont des données de type référence.

python


class SimpleClass {
    var value: Int = 0
}
var x = SimpleClass()          //Première variable x (x.la valeur est initialisée à 0)
var y = SimpleClass()
let closure = { [x] in         //La deuxième constante x (x).la valeur est initialisée à 0)
    print(x.value, y.value)    //Changer x en dehors de la portée a un effet
}

x.value = 10                   //Les modifications hors champ affectent également x dans la liste de capture
y.value = 10
closure()
// Prints "10 10"

Si le type de valeur d'une expression est une classe, vous pouvez marquer l'expression avec «faible» dans la liste de capture pour capturer une «référence faible» à la valeur de l'expression. Vous pouvez également marquer une expression avec «sans propriétaire» dans la liste de capture pour capturer des «références sans propriétaire».

python


myFunction { print(self.title) }                    //Capture de valeurs par "référence forte" (implicite)
myFunction { [self] in print(self.title) }          //Capture de valeurs par "référence forte" (explicite)
myFunction { [weak self] in print(self!.title) }    //Capture de valeurs avec des "références faibles"
myFunction { [unowned self] in print(self.title) }  //Capturez la valeur avec "référence non propriétaire"

Vous pouvez également nommer les valeurs dans la liste de capture et lier n'importe quelle expression. L '"expression liée" est évaluée lorsque la fermeture est créée et la valeur est capturée avec l'intensité spécifiée. Par exemple:

python


// "parent"Comme référence faible"self.parent"Capturer
myFunction { [weak parent = self.parent] in
    print(parent!.title) 
}

Pour plus d'informations et des exemples d'expressions de fermeture, consultez Expressions de fermeture (https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID95). Pour plus d'informations et des exemples de listes de capture, consultez Résolution des cycles de référence de fermeture forte (https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html#ID57).

Recommended Posts

[Swift] Liste de capture
[Swift5] Démarrez ARKit ~ Capture de mouvement ~
Liste thread-safe
Méthode de liste
Liste de travail
Liste de liens