2011-10-09 11 views
6

Tengo una vista con una lógica de dibujo muy compleja (es una vista de mapa que se basa en datos GIS). Hacer este dibujo en el hilo principal bloquea la interfaz de usuario y hace que la aplicación no responda. Quiero alejar el dibujo a un hilo de fondo con, por ejemplo, una NSOperation.Dibujando un hilo de fondo en iOS

¿Cuál es la mejor manera de estructurar esto?

Actualmente estoy dibujando un CGContext fuera de memoria y luego lo convertí en un CGImageRef que envié a la vista para encajar en el hilo principal. Desafortunadamente, esto consume mucha memoria y parece que la aceleración de la GPU ya no se usa, ya que es bastante más lenta. ¿Hay alguna forma de dibujar directamente a la vista desde un hilo de fondo? Sé que UIKit no es seguro para múltiples hilos, pero tal vez haya alguna forma de bloquear la vista mientras hago el dibujo.

Respuesta

1

Nunca me he encontrado con esta situación en el iPhone pero en Mac tuve un problema similar una vez.

  1. Utilice CGLayer para delegar la actividad de dibujo de contextos sin conexión.
  2. Pruebe agregar el temporizador para el NSRunLoop actual y en el intervalo de tiempo ejecute sus comandos gráficos. Debe ser algo como esto ...

...

kRenderFPS 25.0 //This is Maximum value 

renderTimer = [[NSTimer timerWithTimeInterval:(1.0/(NSTimeInterval)kRenderFPS) target:viewobject selector:@selector(RenderUI:) userInfo:nil repeats:YES] retain]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSDefaultRunLoopMode]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSModalPanelRunLoopMode]; 


[[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode]; 

//In view class 
-(void)RenderUI:(id)param 
{ 
    [self setNeedsDisplayInRect:[self bounds]]; 
} 

Esto debería hacer el truco.

También intente muestrear su proceso y comprobar quién consume la CPU. Esto hará que la IU sea receptiva y muy rápida.

El problema de rendimiento que mencionaste puede deberse a otra cosa. Intenta con el proceso de muestra de cpu. Le dará una idea de quién está realmente tomando la CPU.

+0

¿Quieres decir CALayer? –

+1

No. CGLayer. http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGLayer/Reference/reference.html – MacGeek

+0

Así que estoy intentando este enfoque ahora, pero incluso si corro con un NSTimer y ejecuto solo el 50% del tiempo (se ejecuta en intervalos de 0.2 seg para un máximo de 0.1s por ciclo de dibujo) parece que todavía ignora todos los eventos de UI. Hay un truco para esto? –

6

Más allá de iOS 4.0, drawing is thread safe. Puede que necesite crear un CGContext usted mismo, pero no hay ninguna razón por la que no pueda dibujar en una cadena de fondo.

Dicho esto, la mayoría de las operaciones de UIKit no lo son. Si necesita hacer eso, siempre puede prepararse en un hilo de fondo y luego usar performOnMainThread cuando sea necesario. Incluso hay waitUntilDone. Dicho esto, debe usar NSOperation y NSOperationQueue, al parecer.

+1

Parece haber mucha confusión al respecto, pero esta es la respuesta correcta, ya que iOS 4.0 con UIKit es seguro para subprocesos. Aquí está el anuncio oficial de esto: http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html (busque "hilo"). –

+0

@Jon Tirsen, gracias por la ayuda que corrobora la respuesta. –

Cuestiones relacionadas