IOS semaphore_wait_trap в основном потоке, вызывающем зависание в пользовательском интерфейсе
У меня есть длинная функция внутри асинхронной (последовательной) рабочей очереди.
Я знаю, что иногда эта функция зависает внутри определенного вызова openCV.
По какой-то причине это зависание также вызывает зависание основного потока.
При приостановке и входе в режим отладки я вижу, что есть вызов
semaphore_wait_trap()
в основном потоке (очередь)
Я могу приостановить зависающий поток (моя рабочая очередь) в режиме отладки, а затем эта ловушка уходит, и графический интерфейс снова реагирует на телефон.
После приостановки рабочего потока графический интерфейс реагирует на 1-2 секунды (я подозреваю, что этот поток снова активируется), а затем пользовательский интерфейс снова перестает отвечать на запросы.
В этом потоке нет вызовов dispatch_sync()
к основному потоку/очереди
Возможно ли, что IOS приостанавливает основной поток ( "ловушки" ), потому что рабочий работает долго?
Могу ли я заставить его удалить блок?
Я добавляю несколько экранов печати в стеке режима отладки.
Перед тем, как приостановить вешающую очередь:
![Main Queue Stack]()
И висячий поток:
![Hanging Queue]()
И после приостановки и приостановки неудачной очереди:
![After Suspending]()
Ответы
Ответ 1
Возможно ли, что IOS приостанавливает основной поток ( "ловушки" ), потому что рабочий работает долго? - НЕТ.
Я думаю, ваша проблема связана с рисованием или изменением некоторых элементов пользовательского интерфейса. Не все функции могут быть вызваны из фонового потока (например, изменения в элементах пользовательского интерфейса должны выполняться в основном потоке). В вашей последовательной очереди, если какой-либо метод должен изменить элементы пользовательского интерфейса, вы должны вызвать его в основном потоке, например,
dispatch_async(dispatch_get_main_queue(), ^{
//do some main thread job here
});
)
Ответ 2
Может быть, вы просто забыли сохранить переменную в вызове функции отправки. (Как и для меня, я не указывал статическое ключевое слово перед объявлением dispatch_once_t, и отправка не могла обрабатываться с помощью встроенной функции). Трассировка стека была такой же, как ваша. Это была моя ошибка.
+ (instancetype)sharedInstance
{
(static was omitted) dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}