¿Cómo evitar el locking de la interfaz de usuario al usar la camera del iPhone a través de AVFoundation?

Estoy intentando insert una vista simple en mi aplicación de iPhone para tomar instantáneas rápidas. Todo funciona bien, pero estoy enfrentando algunos problemas con el time de inicio de las cameras. En un proyecto de ejemplo de Apple, AVCaptureSession -startRunning no se ejecuta en el hilo principal, lo que parece ser necesario. Estoy configurando la session de captura durante la initialization de la vista, así como comenzando en un hilo por separado. Ahora agrego AVCaptureVideoPreviewLayer en -didMoveToSuperview . Todo está bien sin multihilo (la interfaz de usuario está bloqueada por aproximadamente un segundo) pero con GCD la interfaz de usuario a veces funciona, a veces tarda demasiado time en que la interfaz de usuario se "descongele" o se muestre la vista previa.

¿Cómo puedo manejar el retraso de inicio de la camera de manera confiable, sin bloquear el hilo principal (el retraso en sí no es el problema)?

Espero que ustedes entiendan mi problema: D

¡Gracias por adelantado!

BTW: aquí está mi proof-of-concept-project (sin GCD) Ahora estoy reutilizando para otra aplicación: http://github.com/dariolass/QuickShotView

Entonces me di count por mi count. Este código funciona para mí y produce la menor congelación de la interfaz de usuario:

 - (void)willMoveToSuperview:(UIView *)newSuperview { //capture session setup AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.rearCamera error:nil]; AVCaptureStillImageOutput *newStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; [newStillImageOutput setOutputSettings:outputSettings]; AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; if ([newCaptureSession canAddInput:newVideoInput]) { [newCaptureSession addInput:newVideoInput]; } if ([newCaptureSession canAddOutput:newStillImageOutput]) { [newCaptureSession addOutput:newStillImageOutput]; self.stillImageOutput = newStillImageOutput; self.captureSession = newCaptureSession; } // -startRunning will only return when the session started (-> the camera is then ready) dispatch_queue_t layerQ = dispatch_queue_create("layerQ", NULL); dispatch_async(layerQ, ^{ [self.captureSession startRunning]; AVCaptureVideoPreviewLayer *prevLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession]; prevLayer.frame = self.previewLayerFrame; prevLayer.masksToBounds = YES; prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; prevLayer.cornerRadius = PREVIEW_LAYER_EDGE_RADIUS; //to make sure were not modifying the UI on a thread other than the main thread, use dispatch_async w/ dispatch_get_main_queue dispatch_async(dispatch_get_main_queue(), ^{ [self.layer insertSublayer:prevLayer atIndex:0]; }); }); } 

Creo que otra forma de evitar es que puedes poner tu código de "inicio de camera" en viewDidAppear, en lugar de ponerlos en viewWillAppear.