La version courte
Le type de posséder votre appel à l' FirebaseRef.observeSingleEvent(of:with:)
est probablement un type de valeur (un struct
?), dans ce cas, une mutation du contexte peut ne pas explicitement capture self
en @escaping
fermeture.
La solution la plus simple est de mettre à jour votre propriétaire type de référence une fois (class
).
La version longue
L' observeSingleEvent(of:with:)
méthode de Firebase est déclarée comme suit
func observeSingleEvent(of eventType: FIRDataEventType,
with block: @escaping (FIRDataSnapshot) -> Void)
L' block
fermeture est marqué avec l' @escaping
attribut de paramètre, ce qui signifie qu'il peut quitter le corps de sa fonction, et même la durée de vie d' self
(dans ce contexte). Grâce à cette connaissance, nous construisons un plus minime exemple que nous pouvons analyser:
struct Foo {
private func bar(with block: @escaping () -> ()) { block() }
mutating func bax() {
bar { print(self) } // this closure may outlive 'self'
/* error: closure cannot implicitly capture a
mutating self parameter */
}
}
Maintenant, le message d'erreur devient de plus en plus d'histoires, et nous nous tournons vers l'évolution suivante de la proposition a été mis en œuvre dans Swift 3:
En indiquant [c'est moi qui souligne]:
La capture d'une inout
paramètre, y compris self
en mutation
méthode, devient une erreur dans un escapable fermeture littérale, à moins que le
la capture est faite explicite (et donc immuable).
Maintenant, c'est un point clé. Pour une valeur de type (par exemple, struct
), ce qui je crois est aussi le cas pour le type qui possède l'appel à l' observeSingleEvent(...)
dans votre exemple, une telle explicite de capture n'est pas possible, autant que je sache (puisque nous travaillons avec un type de valeur, et non une référence à l'un).
La plus simple solution de ce problème serait de faire le type de propriétaire de la observeSingleEvent(...)
d'un type de référence, par exemple, un class
, plutôt qu'un struct
:
class Foo {
init() {}
private func bar(with block: @escaping () -> ()) { block() }
func bax() {
bar { print(self) }
}
}
Méfiez-vous cependant que cela permettra de capturer self
par une référence forte; en fonction de votre contexte (je n'ai pas utilisé Firebase moi-même, donc je ne sais pas), vous pouvez explicitement capture self
faiblement, par exemple
FirebaseRef.observeSingleEvent(of: .value, with: { [weak self] (snapshot) in ...