2009-03-31 11 views
9

estoy dibujando fuera de la pantalla a un CGContext creada usando CGBitmapContextCreate, luego generar una CGImage de ella con CGBitmapContextCreateImage y el dibujo que en mi punto de vista en drawRect (También estoy dibujando algunas otras cosas además de eso - se trata de un ejercicio de aislar diferentes niveles de variabilidad y complejidad).Usando Core Graphics/Cocoa, ¿puedes dibujar en un contexto de mapa de bits desde un hilo de fondo?

Todo funciona bien cuando todo se ejecuta en el hilo principal. Sin embargo, una de las motivaciones para dividir esto de esta manera fue que la parte fuera de pantalla se podía ejecutar en un hilo de fondo (lo que pensé que debería estar bien ya que no se está renderizando en un contexto en pantalla).

Sin embargo, cuando lo hago, ¡la imagen resultante está vacía! Revisé el código y coloqué juiciosamente NSLog para verificar que todo esté sucediendo en el orden correcto.

Mi próximo paso es reducir esto al código más simple que reproduce el problema (o encontrar algo tonto que me falta y arreglarlo) - en ese punto tendría algún código para publicar aquí si es necesario. Pero primero quería comprobar aquí que no voy por el camino equivocado con esto. No pude encontrar nada en mis viajes alrededor de la esfera de hielo que arroje luz en ambos sentidos, pero un amigo mencionó que se encontró con un problema similar al intentar cambiar el tamaño de las imágenes en un hilo de fondo, sugiriendo que puede haber alguna limitación general aquí.

[editar]

Gracias por las respuestas hasta el momento. Si nada más me han dicho que al menos no estoy solo porque no tengo una respuesta para esto, que era parte de lo que quería averiguar. En este punto, voy a poner el trabajo extra para obtener el ejemplo más simple posible y puedo regresar con algún código o más información. Mientras tanto, guarde las ideas siguientes :-)

Un punto a tener en cuenta: un par de personas han usado el término thread safety con respecto a las API. Debe tenerse en cuenta que hay dos tipos de hilo de seguridad en este contexto:

  1. Threadability de la API de sí mismo - es decir, ¿Se puede utilizar en absoluto de más de un hilo (estado global y otros problemas de re-entrada tales como strtok de C son razones comunes por las que una API podría no ser segura también para subprocesos).
  2. Atomicidad de operaciones individuales: ¿pueden interactuar varios subprocesos con los mismos objetos y recursos a través de API sin bloqueo de nivel de aplicación?

Sospecho que mencionar hasta ahora ha sido del primer tipo, pero agradecería si pudiera aclarar.

[Edit2 - solucionado]

Ok, lo tengo todo el funcionamiento. El resumen ejecutivo es que el problema estaba conmigo, en lugar de los contextos de los mapas de bits.

En mi hilo de fondo, justo antes de dibujar en el contexto del mapa de bits, estaba preparando algunos otros objetos. Resulta que, indirectamente, las llamadas a esos otros objetos llevan a llamar a setNeedsDisplay en algunas vistas. Al separar la parte que hizo eso del hilo principal, ahora todo funciona perfectamente.

Así que para cualquiera que se meta en esta pregunta preguntándose si pueden dibujar en un contexto de mapa de bits en un hilo de fondo, la respuesta es que puede (con las advertencias que se han presentado aquí y en las respuestas).

Gracias a todos

+1

Su descripción detallada de su problema y solución me ayudó a descubrir qué problema tenía mi propio código. ¡Muchas gracias! – Kalle

Respuesta

3

Solo supongo, pero si intentas llamar a setNeedsDisplay desde otro hilo, debes llamarlo a través de performSelectorOnMainThread.

+0

Gracias. Pero lo estoy llamando desde el hilo principal. Lo único que estoy haciendo en el otro hilo es dibujar en el contexto de mapa de bits – philsquared

+0

Estoy marcando el suyo como aceptado porque resultó ser el más cercano a la causa, incluso si no me llevó directamente a esto :-) – philsquared

0

No todas las API son seguros para subprocesos. Algunos requieren bloqueo o requieren que se ejecuten en el hilo principal. Es posible que desee buscar la documentación. Creo que hay una página que resume qué partes del SDK son seguras para hilos y cuáles no.

+0

Gracias Kailoa. Aprecio la respuesta, pero aquí es más o menos de donde comencé. Esperaba obtener más detalles, ya que mi "búsqueda de la documentación" aún no ha arrojado nada definitivo. – philsquared

2

Lo que está haciendo debería funcionar si está trabajando con CGContextRef en un solo hilo. He hecho esto antes con 8 núcleos trabajando en 8 partes diferentes de una imagen y luego compongo los diferentes CGImageRefs resultantes juntos y dibujándolos en pantalla.

+0

Gracias. No lo mencioné en mi pregunta, pero agregué la etiqueta de iPhone, que puede o no ser significativa aquí (como también mencionó Roger Nolan en su respuesta) – philsquared

1

Apple no dice nada sobre la seguridad de hilos en iPhone, pero Cocoa (en comparación con UIKit) es generally thread safe for drawing. Como comparten una gran cantidad de código de dibujo, supongo que dibujar en iPhone es seguro.

Dicho esto, su experiencia implicaría que hay problemas. ¿Podría ser que estás usando tu imagen antes de que se represente?

+0

No. Al final de mi método de hilo, establecí una llamada a otro método en el hilo principal, que a su vez llama a setNeedsDisplay. Solo en ese punto la imagen se genera fuera del contexto del mapa de bits y se usa para dibujar en la vista – philsquared

0

En caso de que alguien esté buscando exactamente cómo hacerlo, he escrito un blog post que describe cómo hacerlo, y lo envuelve todo en una subclase de NSOperation.

Cuestiones relacionadas