J'essaie de rendre certaines vues dans le fil de fond pour ne pas affecter le fil principal. Ce n'était jamais un problème avant Xcode 9.
DispatchQueue.global(qos: .background).async {
let customView = UIView(frame: .zero)
DispatchQueue.main.async {
self.view.addSubview(customView)
}
}
UIView.init (frame :) doit être utilisé à partir du thread principal uniquement
Cette erreur se produit dans la deuxième ligne.
Mise à jour
La documentation Apple UIView
] indique en fait dans la section Considérations relatives au threading :
Les manipulations sur l'interface utilisateur de votre application doivent être effectuées sur le thread principal. Ainsi, vous devriez toujours appeler les méthodes de la classe UIView à partir du code exécuté dans le thread principal de votre application. La seule fois où cela peut ne pas être strictement nécessaire, c'est lors de la création de l'objet de vue lui-même, mais toutes les autres manipulations doivent avoir lieu sur le thread principal.
Xcode 9 a un nouveau runtime Vérificateur de thread principal qui détecte l'appel à UIKit à partir d'un thread en arrière-plan et génère des avertissements.
Je sais que son objectif est de générer des avertissements et de ne pas bloquer l'application, mais vous pouvez essayer de désactiver le vérificateur de thread principal pour votre cible de test.
J'ai essayé ce code dans un exemple de projet, le débogueur s'est arrêté sur le problème (comme il est supposé le faire), mais l'application ne s'est pas bloquée.
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let v = UIView(frame: .zero)
}
}
Vous pouvez utiliser cette fonction
func downloadImage(urlstr: String, imageView: UIImageView) {
let url = URL(string: urlstr)!
let task = URLSession.shared.dataTask(with: url) { data, _, _ in
guard let data = data else { return }
DispatchQueue.main.async { // Make sure you're on the main thread here
imageview.image = UIImage(data: data)
}
}
task.resume()
}
Comment utiliser cette fonction?
downloadImage(urlstr: "imageUrl", imageView: self.myImageView)
Vous pouvez entrer le fil principal comme suit
DispatchQueue.main.async {
// UIView usage
}