AVCaptureSession - Stop Running - займет много времени
Я использую ZXing для приложения, это в основном тот же код, что и исходный код ZXing, за исключением того, что я позволяю сканировать несколько раз подряд (т. Е. ZXingWidgetController не исключается незамедлительно, как только что-то обнаруживается).
Я испытываю длительное замораживание (иногда это никогда не заканчивается), когда я нажимаю кнопку отклонения, которая вызывает
- (void)cancelled {
// if (!self.isStatusBarHidden) {
// [[UIApplication sharedApplication] setStatusBarHidden:NO];
// }
[self stopCapture];
wasCancelled = YES;
if (delegate != nil) {
[delegate zxingControllerDidCancel:self];
}
}
с
- (void)stopCapture {
decoding = NO;
#if HAS_AVFF
if([captureSession isRunning])[captureSession stopRunning];
AVCaptureInput* input = [captureSession.inputs objectAtIndex:0];
[captureSession removeInput:input];
AVCaptureVideoDataOutput* output = (AVCaptureVideoDataOutput*)[captureSession.outputs objectAtIndex:0];
[captureSession removeOutput:output];
[self.prevLayer removeFromSuperlayer];
/*
// heebee jeebees here ... is iOS still writing into the layer?
if (self.prevLayer) {
layer.session = nil;
AVCaptureVideoPreviewLayer* layer = prevLayer;
[self.prevLayer retain];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 12000000000), dispatch_get_main_queue(), ^{
[layer release];
});
}
*/
self.prevLayer = nil;
self.captureSession = nil;
#endif
}
(обратите внимание, что dismissModalViewController, который удаляет представление, находится в методе делегата)
Я замерзаю только при увольнении, только если я сделал несколько сканов подряд, и только с iPhone 4 (без замораживания с 4S)
Любая идея?
ура
ПЗУ
1 ответ
В соответствии с примером контроллера AVCamView вызов startRunning или stopRunning не возвращается, пока сеанс не завершит запрошенную операцию. Поскольку вы отправляете эти сообщения сеансу в главном потоке, он блокирует весь пользовательский интерфейс до завершения запрошенной операции. Я бы порекомендовал вам обернуть ваши вызовы в асинхронную диспетчеризацию, чтобы представление не блокировалось.
- (void)cancelled
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self stopCapture];
});
//You might want to think about putting the following in another method
//and calling it when the stop capture method finishes
wasCancelled = YES;
if (delegate != nil) {
[delegate zxingControllerDidCancel:self];
}
}