остановка AVCaptureSession iPhone занимает 8 секунд

Я создаю новый сеанс и запускаю его на iPhone следующим образом:

AVCaptureSession* session;
...
[session startRunning];

Это прекрасно работает. Однако, остановив сеанс позже:

[session stopRunning];

Обычно это занимает около 8 секунд! Кто-нибудь знает, почему это возможно и что можно сделать, чтобы сделать это быстрее?


person Jan Rüegg    schedule 03.07.2013    source источник
comment
Попробуйте это: stackoverflow .com/questions/11905505/   -  person nickcheng    schedule 29.08.2013
comment
Да, похоже, это решает проблему. Когда вы добавите это как ответ, я приму это.   -  person Jan Rüegg    schedule 29.08.2013


Ответы (2)


Я столкнулся с похожей проблемой. Вызов stopRunning заморозит приложение на 8-10 секунд.

В конце концов я отследил проблему до этого: я вызывал stopRunning в потоке, отличном от основного потока. Этот вторичный поток использовался для всех транзакций в AVCaptureSession. Проблема возникла из-за того, что после отправки вызова stopRunning я заблокировал основной поток, ожидая его завершения. К сожалению, stopRunning отправляет что-то в основной поток и блокируется, ожидая его завершения. Время ожидания объекта stopRunning истекло, и он сообщил об ошибке в обратном вызове - (void)onRuntimeError:(NSNotification*)n: Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo=0x19e43c90 {NSLocalizedRecoverySuggestion=Попробуйте позже ., NSLocalizedDescription=Невозможно выполнить действие}

Решение в моем случае состояло в том, чтобы просто не блокировать основной поток после вызова stopRunning. К счастью для меня, это было легко сделать (и Apple в любом случае более или менее рекомендует это).

Я заметил вариации на эту тему в других вопросах, и решение всегда заключалось в переработке кода. Надеюсь, это поможет лучше понять, почему возникает проблема.

person Chris Cooksey    schedule 12.08.2014
comment
Это заставило меня заметить, что я вызывал startRunning() в своем приложении вне основного потока, что вызывало длительную задержку перед началом сеанса. Я изменил его, чтобы он работал в основном потоке, и он снова работает правильно. - person David Brunow; 29.05.2015

Из документов Apple:

Обсуждение

Этот метод используется для остановки потока данных от входов к выходам, подключенным к экземпляру AVCaptureSession, который является получателем. Этот метод является синхронным и блокируется до тех пор, пока работа приемника полностью не прекратится.

Поскольку он синхронный, вы можете поместить его в асинхронный вызов, чтобы избежать зависания потока пользовательского интерфейса.


Добавление дополнительных комментариев:

Идея выше не сделала stopRunning быстрее. Это просто перестанет замораживать поток пользовательского интерфейса.

person nickcheng    schedule 29.08.2013