iphone - NSDefaultRunLoopMode vs NSRunLoopCommonModes
ios multithreading (1)
Querida buena gente de stackoverflow,
Al igual que la última vez, presento una pregunta con la que me tropecé recientemente. Espero que alguien por ahí pueda arrojar algo de luz sobre mí.
Cada vez que intento descargar un gran archivo detrás de UIScrollView
, MPMapView
o algo así, el proceso de descarga se detiene tan pronto como toco la pantalla del iPhone. Afortunadamente, una publicación de blog increíble por Jörn sugiere una opción alternativa, utilizando NSRunLoopCommonModes
para la conexión.
Eso me permite ver los detalles de los dos modos, NSDefaultRunLoopMode y NSRunLoopCommonModes, pero el documento de Apple no explica amablemente, aparte de decir
NSDefaultRunLoopMode
El modo para tratar con fuentes de entrada distintas de los objetos NSConnection. Este es el modo de ciclo de ejecución más comúnmente utilizado.
NSRunLoopCommonModes
Los objetos añadidos a un bucle de ejecución utilizando este valor como modo son supervisados por todos los modos de bucle en ejecución que se han declarado como un miembro del conjunto de modos "comunes"; consulte la descripción de CFRunLoopAddCommonMode para obtener más información.
CFRunLoopAddCommonMode
Las fuentes, los temporizadores y los observadores se registran en uno o más modos de ciclo de ejecución y solo se ejecutan cuando el ciclo de ejecución se ejecuta en uno de esos modos. Los modos comunes son un conjunto de modos de ciclo de ejecución para los que puede definir un conjunto de fuentes, temporizadores y observadores que comparten estos modos. En lugar de registrar una fuente, por ejemplo, para cada modo de ciclo de ejecución específico, puede registrarla una vez en el pseudo-modo común del ciclo de ejecución y se registrará automáticamente en cada modo de ciclo de ejecución en el conjunto de modos comunes. Del mismo modo, cuando se agrega un modo al conjunto de modos comunes, cualquier fuente, temporizador u observador ya registrado en el pseudo-modo común se agrega al modo común recién agregado.
¿Alguien puede explicar los dos en lenguaje humano?
Un ciclo de ejecución es un mecanismo que permite que el sistema active subprocesos para dormir para que puedan administrar eventos asincrónicos. Normalmente cuando ejecuta un hilo (a excepción del hilo principal) hay una opción para iniciar el hilo en un ciclo de ejecución o no. Si el subproceso ejecuta algún tipo de operación de larga ejecución sin interacción con eventos externos y sin temporizadores, no necesita un ciclo de ejecución, pero si su subproceso necesita responder a eventos entrantes, debe adjuntarse a un ciclo de ejecución para Despertar el hilo cuando lleguen nuevos eventos. Este es el caso de los NSURLConnection
generados por NSURLConnection
, ya que solo se activan en los eventos entrantes (desde la red).
Cada subproceso se puede asociar a varios bucles de ejecución o se puede asociar a un bucle de ejecución específico que se puede configurar para que funcione en diferentes modos. Un "modo de ciclo de ejecución" es una convención utilizada por el sistema operativo para establecer algunas reglas sobre cuándo entregar ciertos eventos o recopilarlos para entregarlos más tarde.
Por lo general, todos los bucles de ejecución se configuran en el "modo predeterminado", que establece una forma predeterminada de administrar los eventos de entrada. Por ejemplo: tan pronto como ocurre un evento de arrastrar ratón (Mac OS) o táctil (en iOS), el modo para este ciclo de ejecución se establece en seguimiento de eventos; esto significa que el hilo no se activará en nuevos eventos de red, pero estos eventos se enviarán más tarde cuando el evento de entrada del usuario finalice y el bucle de ejecución vuelva a establecerse en modo predeterminado; obviamente, esta es una elección hecha por los arquitectos del sistema operativo para dar prioridad a los eventos del usuario en lugar de eventos de fondo.
Si decide cambiar el modo de ciclo de ejecución para su subproceso NSURLConnection
, utilizando scheduleInRunLoop:forModes:
puede asignar el subproceso a un modo de bucle de ejecución especial, en lugar del bucle de ejecución predeterminado específico. El pseudo-modo especial llamado NSRunLoopCommonModes
es utilizado por muchas fuentes de entrada, incluido el seguimiento de eventos. Por ejemplo, la asignación de la instancia de NSURLConnection
al modo común significa que asocia sus eventos al "modo de seguimiento" además del "modo predeterminado". Una ventaja / desventaja de asociar hilos con NSRunLoopCommonModes
es que el hilo no será bloqueado por eventos táctiles.
Se pueden agregar modos nuevos a los modos comunes, pero esta es una operación de bajo nivel.
Me gustaría cerrar agregando algunas notas:
Por lo general, necesitamos utilizar un conjunto de imágenes o miniaturas descargadas de la red con una vista de tabla. Podemos pensar que la descarga de estas imágenes desde la red mientras se desplaza la vista de tabla podría mejorar la experiencia del usuario (ya que podríamos ver las imágenes mientras se desplaza), pero esto no es ventajoso ya que la fluidez del desplazamiento puede sufrir mucho. En este ejemplo con
NSURLConnection
, no se debe usar un ciclo de ejecución; sería mejor utilizar los métodos de delegadoUIScrollView
para detectar cuándo finaliza el desplazamiento y luego actualizar la tabla y descargar nuevos elementos de la red;Puede considerar usar GCD, que lo ayudará a "proteger" su código de los problemas de administración del bucle de ejecución. En el ejemplo anterior, puede considerar agregar sus solicitudes de red a una cola serial personalizada.