web-dev-qa-db-fra.com

Utilisation de dispatch_async avec self

J'ai rencontré ce problème plusieurs fois lors du portage du code Objective-C vers Swift. Disons que j'ai le code suivant:

dispatch_async(dispatch_get_main_queue()) {
    self.hostViewController?.view.addSubview(self.commandField)
}

Cela entraînera une erreur, soulignant l'ensemble dispatch_async appeler, offrant:

Could not find member 'addSubview'

Je suppose que c'est une erreur qui n'a pas encore été correctement implémentée car si je mets l'appel addSubview en dehors de dispatch_async block, le projet se construit bien. Au départ, je supposais que cela pouvait avoir quelque chose à voir avec la capture de self dans le bloc. Cependant, l'insertion de [unowned self] in entraîne la même erreur, tout comme [weak self] in (après le ! des opérateurs de déballage ont été insérés).

Comment puis-je avoir dispatch_async blocs pour travailler dans Swift qui doivent capturer self?

42
Ephemera

Vous devez conditionner la rotation de cette action à la non-nullité, et non la tester après l'avoir déjà lancée:

if let hostView = self.hostViewController?.view {
    DispatchQueue.main.async {
         hostView.addSubview(self.commandField)
    }
} else {
    // handle nil hostView 
}

Vous ne devez jamais déballer une option en dehors d'un if let, ou le tester d'abord. Cela devrait également résoudre votre problème d'auto faible.

65
iluvcapra

Le dispatch_async la syntaxe a changé avec Swift 3:

DispatchQueue.main.async { 
    hostView.addSubview(self.commandField)
}
12
JAL