Obteniendo el mensaje “Esta aplicación está modificando el motor del autolayout de un hilo de fondo”?

He encontrado mucho este error en mi OS X usando swift:

“Esta aplicación está modificando el motor de ajuste automático de una secuencia de fondo, lo que puede provocar daños en el motor y lockings extraños. Esto provocará una excepción en una versión futura”.

Tengo una NSWindow y estoy intercambiando vistas del contentView de la ventana. NSApp.beginSheet el error cuando bash hacer un NSApp.beginSheet en la ventana o cuando agrego una subview a la ventana. Intenté deshabilitar las cosas de autoresize, y no tengo nada usando el diseño automático. ¿Alguna idea?

A veces está bien y no pasa nada, otras veces rompe por completo mi UI y nada carga

De acuerdo, encontré la respuesta. Debe colocarse dentro de un hilo diferente que permita que la IU se actualice tan pronto como se complete la ejecución de la función de hilo:

Swift 3

  DispatchQueue.main.async { // Update UI } 

Versión Swift <3

 dispatch_async(dispatch_get_main_queue(){ // code here }) 

Versión Objective-C

 dispatch_async(dispatch_get_main_queue(), ^{ // code here }); 

Obtiene un mensaje de error similar al depurar con instrucciones de impresión sin usar ‘dispatch_async’ Entonces, cuando recibe ese mensaje de error, es hora de usar

Swift 4

 DispatchQueue.main.async { //code } 

Swift 3

 DispatchQueue.main.async(){ //code } 

Versiones anteriores Swift

 dispatch_async(dispatch_get_main_queue()){ //code } 

Usé la respuesta @markussvensson para detectar mi problema, lo encontré usando este punto de ruptura simbólico :

  1. Símbolos: [UIView layoutIfNeeded] o [UIView updateConstraintsIfNeeded]
  2. Condición !(BOOL)[NSThread isMainThread]

enter image description here

Cuando intenta actualizar un valor de campo de texto o agregar una subvista dentro de una cadena de fondo, puede obtener este problema. Por esa razón, debe poner este tipo de código en el hilo principal.

Debe envolver los métodos que llaman a las actualizaciones de UI con dispatch_asynch para obtener la cola principal. Por ejemplo:

 dispatch_async(dispatch_get_main_queue(), { () -> Void in self.friendLabel.text = "You are following \(friendCount) accounts" }) 

EDITADO – SWIFT 3:

Ahora, podemos hacer eso siguiendo el siguiente código:

 // Move to a background thread to do some long running work DispatchQueue.global(qos: .userInitiated).async { // Do long running task here // Bounce back to the main thread to update the UI DispatchQueue.main.async { self.friendLabel.text = "You are following \(friendCount) accounts" } } 

Para mí, este mensaje de error se originó a partir de un banner de Admob SDK.

Pude rastrear el origen a “WebThread” estableciendo un punto de interrupción condicional.

punto de interrupción condicional para encontrar quién está actualizando ui desde el hilo de fondo

Luego pude deshacerme del problema al encapsular la creación de Banner con:

 dispatch_async(dispatch_get_main_queue(), ^{ _bannerForTableFooter = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait]; ... } 

No sé por qué esto ayudó ya que no puedo ver cómo se llamó este código desde un hilo no principal.

Espero que pueda ayudar a cualquiera.

Tuve este problema desde que actualicé el iOS 9 SDK cuando estaba llamando a un bloque que realizaba actualizaciones de UI dentro de un controlador de finalización de solicitud asincrónico NSURLConnection. Poner la llamada al bloque en un dispatch_async usando dispatch_main_queue resolvió el problema.

Funcionó bien en iOS 8.

Tuve el mismo problema porque estaba usando performSelectorInBackground .

¡No debe cambiar la UI fuera de juego en el hilo principal! UIKit no es seguro para subprocesos, por lo que el problema anterior y también otros problemas extraños surgirán si lo haces. La aplicación incluso puede bloquearse.

Entonces, para hacer las operaciones de UIKit, necesita definir el bloque y dejar que se ejecute en la cola principal, como

 NSOperationQueue.mainQueue().addOperationWithBlock { } 

Obviamente estás haciendo alguna actualización de UI en el hilo de fondo. No puedo predecir exactamente dónde, sin ver tu código.

Estas son algunas situaciones en las que podría suceder:

es posible que estés haciendo algo en el hilo de fondo y no estés usando. Al estar en la misma función, este código es más fácil de detectar.

 DispatchQueue.main.async { // do UI update here } 

llamando a un func haciendo una llamada a la solicitud web en el hilo de fondo y su manejador de finalización llamando a otra func haciendo la actualización de ui. para resolver este bash, compruebe el código en el que ha actualizado la IU después de la llamada de la llamada a la red.

 // Do something on background thread DispatchQueue.global(qos: .userInitiated).async { // update UI on main thread DispatchQueue.main.async { // Updating whole table view self.myTableview.reloadData() } } 

Tuve este problema al volver a cargar los datos en UITableView. Simplemente, enviar la recarga de la siguiente manera me solucionó el problema.

  dispatch_async(dispatch_get_main_queue(), { () -> Void in self.tableView.reloadData() }) 

Yo tuve el mismo problema. Resulta que estaba usando UIAlerts que necesitaba la cola principal. Pero, han sido desaprobados .
Cuando cambié el UIAlerts al UIAlertController , ya no tuve el problema y no tuve que usar ningún código dispatch_async . La lección: presta atención a las advertencias. Ayudan incluso cuando no lo esperas.

Ya tiene la respuesta correcta del código de @Mark pero, solo para compartir mis hallazgos: El problema es que está solicitando un cambio en la vista y suponiendo que sucederá instantáneamente. En realidad, la carga de una vista depende de los recursos disponibles. Si todo se carga lo suficientemente rápido y no hay retrasos, entonces no se nota nada. En los escenarios, donde hay un retraso debido a que el hilo del proceso está ocupado, etc., la aplicación se encuentra con una situación en la que se supone que debe mostrar algo, aunque todavía no está listo. Por lo tanto, es aconsejable enviar estas solicitudes en una cola asincrónica para que se ejecuten en función de la carga.

Tuve este problema cuando estaba usando TouchID si eso ayuda a alguien más, envuelva su lógica de éxito que probablemente hace algo con la interfaz de usuario en la cola principal.

Podría ser algo tan simple como establecer un valor de campo / etiqueta de texto o agregar una subvista dentro de una cadena de fondo, lo que puede hacer que cambie el diseño de un campo. Asegúrese de que todo lo que haga con la interfaz solo ocurra en el hilo principal.

Mira este enlace: https://forums.developer.apple.com/thread/7399

Tuve el mismo problema al tratar de actualizar el mensaje de error en UILabel en el mismo ViewController (lleva un poco de tiempo actualizar los datos cuando intenta hacer eso con la encoding normal). Utilicé DispatchQueue en Swift 3 Xcode 8 y funciona.

Para mí, el problema fue el siguiente. Asegúrese de que performSegueWithIdentifier: se realice en el hilo principal:

 dispatch_async (dispatch_get_main_queue(), ^{ [self performSegueWithIdentifier:@"ViewController" sender:nil]; }); 

Swift 4,

Supongamos, si está llamando a algún método utilizando cola de operación

 operationQueue.addOperation({ self.searchFavourites() }) 

Y supongamos que la función searchFavourites es como,

 func searchFavourites() { DispatchQueue.main.async { //Your code } } 

si llama, todo el código dentro del método “searchFavourites” en el hilo principal, aún dará un error si está actualizando alguna UI en él.

Esta aplicación está modificando el motor de autodiseño de un hilo de fondo después de acceder al motor desde el hilo principal.

Entonces usa solución,

 operationQueue.addOperation({ DispatchQueue.main.async { self.searchFavourites() } }) 

Para este tipo de escenario.

También me encontré con este problema, al ver una tonelada de estos mensajes y los rastros de stack que se imprimían en la salida, cuando cambié el tamaño de la ventana a un tamaño más pequeño que su valor inicial. Pasé mucho tiempo descifrando el problema, pensé que compartiría la solución más simple. Una vez habilité Can Draw Concurrently NSTextView en un NSTextView través de IB. Eso le dice a AppKit que puede llamar al método draw(_:) de otra cadena. Después de desactivarlo, ya no recibí ningún mensaje de error. No experimenté ningún problema antes de actualizar a macOS 10.14 Beta, pero al mismo tiempo, también comencé a modificar el código para realizar el trabajo con la vista de texto.