He estado encontrando mucho este error en mi OS X usando swift:
"Esta aplicación está modificando el motor de reproducción automática desde un subproceso en segundo plano, lo que puede provocar daños en el motor y bloqueos extraños. Esto provocará una excepción en una versión futura".
Tengo mi NSWindow y estoy intercambiando vistas contentView
de la ventana. Recibo el error cuando intento hacer un NSApp.beginSheet
en la ventana o cuando agrego un subview
a la ventana. Intenté deshabilitar cosas de tamaño automático, y no tengo nada usando el diseño automático. ¿Alguna idea?
A veces está bien y no pasa nada, otras veces me rompe por completo UI
y nada se carga
Respuestas:
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 moderno:
Versiones anteriores de Swift, pre Swift 3.
C objetivo:
fuente
Obtiene un mensaje de error similar al depurar con sentencias de impresión sin usar 'dispatch_async'. Entonces, cuando recibe ese mensaje de error, es hora de usar
Swift 4
Swift 3
Versiones anteriores de Swift
fuente
dispatch_async(dispatch_get_main_queue(), ^{ /* UI related code */ });
Editar: actualicé su respuesta, el formato de sintaxis funciona mejor allí.El error "esta aplicación está modificando el motor de reproducción automática desde un subproceso en segundo plano" se registra en la consola mucho después de que ocurriera el problema real, por lo que la depuración puede ser difícil sin usar un punto de interrupción.
Utilicé la respuesta de @ markussvensson para detectar mi problema y lo encontré usando este Punto de interrupción simbólico (Depuración> Puntos de interrupción> Crear punto de interrupción simbólico):
[UIView layoutIfNeeded]
o[UIView updateConstraintsIfNeeded]
!(BOOL)[NSThread isMainThread]
Compile y ejecute la aplicación en el emulador y reproduzca los pasos que conducen al mensaje de error (¡la aplicación será más lenta de lo habitual!). Luego, Xcode detendrá la aplicación y marcará la línea de código (por ejemplo, la llamada de una función) que accede a la interfaz de usuario desde un hilo de fondo.
fuente
movq 0x10880ba(%rip), %rsi ; "_wantsReapplicationOfAutoLayoutWithLayoutDirtyOnEntry:"
Cuando intenta actualizar un valor de campo de texto o agregar una subvista dentro de un hilo de fondo, puede obtener este problema. Por esa razón, debe colocar este tipo de código en el hilo principal.
Debe ajustar los métodos que llaman a las actualizaciones de la interfaz de usuario con dispatch_asynch para obtener la cola principal. Por ejemplo:
EDITADO - SWIFT 3:
Ahora, podemos hacerlo siguiendo el siguiente código:
fuente
Para mí, este mensaje de error se originó en un banner de Admob SDK.
Pude rastrear el origen hasta "WebThread" estableciendo un punto de interrupción condicional.
Luego pude deshacerme del problema encapsulando la creación de Banner con:
No sé por qué esto ayudó, ya que no puedo ver cómo se llamó a este código desde un hilo no principal.
Espero que pueda ayudar a cualquiera.
fuente
Tuve este problema desde que actualicé el SDK de iOS 9 cuando estaba llamando a un bloque que hacía actualizaciones de UI dentro de un controlador de finalización de solicitud asíncrona NSURLConnection. Poner la llamada de bloqueo en un dispatch_async usando dispatch_main_queue resolvió el problema.
Funcionó bien en iOS 8.
fuente
Tuve el mismo problema porque estaba usando
performSelectorInBackground
.fuente
¡No debes cambiar la interfaz de usuario fuera del hilo principal! UIKit no es seguro para subprocesos, por lo que, si lo hace, surgirán problemas anteriores y también otros problemas extraños. La aplicación incluso puede bloquearse.
Entonces, para realizar las operaciones de UIKit, debe definir el bloque y dejar que se ejecute en la cola principal: por ejemplo,
fuente
Obviamente está haciendo alguna actualización de la interfaz de usuario en el hilo de fondo. No puedo predecir exactamente dónde, sin ver su código.
Estas son algunas situaciones que pueden ocurrir:
Es posible que esté haciendo algo en el subproceso de fondo y no lo esté utilizando. Al estar en la misma función, este código es más fácil de detectar.
llamar a una función que realiza una llamada de solicitud web en el subproceso en segundo plano y su controlador de finalización llamando a otra función que realiza la actualización de la interfaz de usuario Para resolver este problema, intente verificar el código donde ha actualizado la interfaz de usuario después de la llamada webrequest.
fuente
El principal problema con "Esta aplicación está modificando el motor de reproducción automática desde un subproceso en segundo plano" es que parece haberse registrado mucho tiempo después de que se produce el problema real, esto puede dificultar la resolución de problemas.
Logré resolver el problema creando tres puntos de interrupción simbólicos.
Depurar> Puntos de interrupción> Crear punto de interrupción simbólico ...
Punto de interrupción 1:
Símbolo:
-[UIView setNeedsLayout]
Condición:
!(BOOL)[NSThread isMainThread]
Punto de interrupción 2:
Símbolo:
-[UIView layoutIfNeeded]
Condición:
!(BOOL)[NSThread isMainThread]
Punto de interrupción 3:
Símbolo:
-[UIView updateConstraintsIfNeeded]
Condición:
!(BOOL)[NSThread isMainThread]
Con estos puntos de interrupción, puede obtener fácilmente un salto en la línea real donde llama incorrectamente a los métodos de IU en un subproceso no principal.
fuente
Tuve este problema al volver a cargar datos en UITableView. Simplemente el envío de recarga de la siguiente manera solucionó el problema para mí.
fuente
Yo tuve el mismo problema. Resulta que estaba usando
UIAlerts
que necesitaba la cola principal. Pero, han sido desaprobados .Cuando cambié
UIAlerts
aUIAlertController
, ya no tuve el problema y no tuve que usar ningúndispatch_async
código. La lección: preste atención a las advertencias. Ayudan incluso cuando no lo esperas.fuente
Ya tiene la respuesta de código correcta de @ Mark pero, solo para compartir mis hallazgos: el problema es que está solicitando un cambio en la vista y suponiendo que sucederá al instante. En realidad, la carga de una vista depende de los recursos disponibles. Si todo se carga lo suficientemente rápido y no hay demoras, entonces no nota nada. En escenarios, donde hay algún 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 muestra algo aunque aún no está listo. Por lo tanto, es aconsejable despachar estas solicitudes en colas asíncronas para que se ejecuten en función de la carga.
fuente
Tuve este problema cuando estaba usando TouchID si eso ayuda a alguien más, ajusta su lógica de éxito que probablemente haga algo con la interfaz de usuario en la cola principal.
fuente
Podría ser algo tan simple como configurar un campo de texto / valor de etiqueta o agregar una subvista dentro de un hilo 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.
Consulte este enlace: https://forums.developer.apple.com/thread/7399
fuente
Tuve el mismo problema al intentar actualizar el mensaje de error en UILabel en el mismo ViewController (se tarda un poco en actualizar los datos al intentar hacerlo con la codificación normal). Utilicé
DispatchQueue
en Swift 3 Xcode 8 y funciona.fuente
Si desea buscar este error, use la casilla de verificación del subproceso principal en los problemas. Solucionarlo es fácil la mayoría de las veces, enviando la línea problemática en la cola principal.
fuente
Para mí el problema fue el siguiente. Asegúrese de que
performSegueWithIdentifier:
se realiza en el hilo principal:fuente
Swift 4,
Supongamos que si está llamando a algún método usando la cola de operaciones
Y supongamos que la función searchFavourites es como,
si llama, todo el código dentro del método "searchFavourites" en el hilo principal, todavía dará un error si está actualizando alguna IU en él.
Entonces usa la solución,
Para este tipo de escenario.
fuente
Aquí mira esta línea de los registros
puede verificar qué función llama desde el subproceso en segundo plano o desde dónde llama al método api, necesita llamar a su función desde el subproceso principal de esta manera.
Registra aquí
fuente
También me encontré con este problema, al ver una tonelada de estos mensajes y rastros de la pila que se imprimen en la salida, cuando cambié el tamaño de la ventana a un tamaño más pequeño que su valor inicial. Al pasar mucho tiempo resolviendo el problema, pensé en compartir la solución bastante simple. Una vez lo había habilitado
Can Draw Concurrently
en unNSTextView
IB. Eso le dice a AppKit que puede llamar aldraw(_:)
método de la vista desde otro hilo. Después de deshabilitarlo, ya no recibo ningún mensaje de error. No tuve 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.fuente