que ios objective-c xcode multithreading uikit

ios - que - Xcode UIView.init(frame:) debe usarse solo desde el hilo principal



que es uikit (3)

Estoy intentando representar algunas vistas en el subproceso de fondo para no afectar al subproceso principal. Eso nunca fue un problema antes de Xcode 9.

DispatchQueue.global(qos: .background).async { let customView = UIView(frame: .zero) DispatchQueue.main.async { self.view.addSubview(customView) } }

UIView.init (frame :) debe usarse solo desde el hilo principal

Este error se produce en la segunda línea.

Actualizar

La documentación de Apple UIView realidad dice en la sección Consideraciones de UIView :

Las manipulaciones a la interfaz de usuario de su aplicación deben ocurrir en el hilo principal. Por lo tanto, siempre debe llamar a los métodos de la clase UIView desde el código que se ejecuta en el hilo principal de su aplicación. La única vez que esto puede no ser estrictamente necesario es cuando se crea el objeto de vista en sí, pero todas las otras manipulaciones deben ocurrir en el hilo principal.


Puedes usar esta función

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() }

¿Cómo utilizar esta función?

downloadImage(urlstr: "imageUrl", imageView: self.myImageView)


Xcode 9 tiene un nuevo verificador de subprocesos principal en tiempo de ejecución que detecta las llamadas a UIKit desde un subproceso en segundo plano y genera advertencias.

Sé que está pensado para generar advertencias y no bloquear la aplicación, pero puedes intentar deshabilitar Main Thread Checker para tu objetivo de prueba.

Intenté este código en un proyecto de muestra, el depurador se detuvo en el problema (como se supone que debe hacerlo), pero la aplicación no se bloqueó.

override func viewDidLoad() { super.viewDidLoad() DispatchQueue.global().async { let v = UIView(frame: .zero) } }


DispatchQueue.main.async { // UIView usage }