2011-01-11 12 views
9

¿Alguien sabe de alguna manera, o tiene una idea creativa sobre cómo obtener un UIImage que se representa desde un UIWebView? El truco es que debe estar en un hilo de fondo.Crea un UIImage reproduciendo UIWebView en un hilo de fondo - iPhone

Voy a elaborar: Estoy tratando de obtener la imagen de múltiples UIWebViews cada segundo + -, y mostrarlo en la pantalla (iPhone, por supuesto). Como renderizar una capa en un CGContext es un trabajo que consume CPU, no me gustaría utilizar el hilo principal, por lo tanto, no para colgar la IU.

Mis intentos hasta ahora han sido:

  • He intentado utilizar renderInContext en la capa de la web View a la UIGraphicalContext, pero el error webviews _WebTryThreadLock estrellé los.

  • Intenté crear un CGBitmapContext y renderizar la capa de la vista web, pero obtuve el mismo resultado.

  • Intenté implementar un método copy (agregando una Categoría) a CALayer, que copió profundamente todas las propiedades públicas y subcapas. Después, traté de renderInContext la capa que copié. Obtuve un UIImage que era parcialmente "correcto", lo que significa que no se procesaron todas las capas, así que, por ejemplo, solo obtendría el encabezado (o pie de página, cuerpo o barra de búsqueda, o solo algunos los marcos). La capa de UIWebview consiste en todo tipo de CALayers subclasificados, por lo que esta es probablemente la razón por la cual este método no funcionó.

  • Intenté configurar el kCATransactionDisableActions en un CATransaction, pero no pareció cambiar este comportamiento (ninguno de ellos).

Estoy muy cerca de renunciar.

¿Hay algún salvador entre ustedes?

+0

+1 pregunta difícil –

Respuesta

4

UIWebView odia, y me refiero a realmente odia, teniendo algo hecho en un hilo de fondo. UIKit no es totalmente seguro para subprocesos. Dibujar en un contexto de gráficos es (esto fue agregado en iOS 4), pero no crear UIViews en un hilo secundario.

¿Está creando sus UIWebViews fuera del hilo principal? ¿Quizás tengas algún código para compartir? Sospecho que tus problemas están causados ​​por el hecho de que intentas realizar operaciones en un UIWebView en un hilo secundario. La operación de dibujo para representar los contenidos de la vista como una imagen puede pasar del hilo principal, pero la creación de la vista no puede hacerlo.

+3

Estoy creando UIWebViews en el hilo principal. No podría estar más de acuerdo con la parte "odia";), y también estoy de acuerdo en que es posible dibujar en un contexto gráfico, pero desafortunadamente, parece que renderizar el diseño de UIWebView parece bloquear, en ciertas condiciones, el hilo asociado con el propio UIWebView (no el hilo principal, pero el que crea iOS para manejarlo), lo que hace que se vuelva loco cuando el bloqueo se realiza mediante un hilo secundario. El diseño de UIWebView se compila con unas pocas subclases privadas de API de CALayer (WebLayer, etc.). – Gilbert

+0

He visto problemas similares anteriormente con las vistas web, aunque también se han limitado al simulador; tiene razón, es probable que tenga que ver con una de las subclases privadas. Lo siento, no puedo ser más ayuda. – lxt

0

He estado trabajando en esto también.

En un hilo, creo una jerarquía de vista, bucleo hasta que la vista web haya terminado de cargar el contenido.

La vista web creo que hay dentro de viewdidload-- de un UIViewController He intentado hacer

if ([NSThread isMainThread] == NO) {[self performselectorOnMainThread: @selector(viewDidLoad)return;)} 

y he hecho lo mismo para dealloc'ing la web View.

Pero eso no funcionó ..Solo he encontrado que evitamos las excepciones de UIWebView HASTA que lleguemos al grupo de liberación automática ...

Estoy usando instrumentos para averiguar por qué.

Aquí está mi estrategia de ataque ... Voy a realizar la operación de renderización en el subproceso principal con una vista fuera de pantalla, con un subproceso independiente ejecutando algún tipo de cola para gestionarlos. Estoy preocupado por el retraso de IU, así que tendrá que ser bastante eficiente.

+0

Sí, ese es el truco ... Realice los selectores para crear el procesamiento en un subproceso separado, consulte el estado de carga en un subproceso secundario, luego represéntelo en el subproceso principal cuando esté listo. – user438350

+2

Esa es básicamente mi solución actual. Pero no es bueno, ya que tengo demasiado retraso de UI debido a eso (y lo único que hago en el hilo principal es el proceso real de renderización del núcleo). – Gilbert

Cuestiones relacionadas