IOS semaphore_wait_trap в основном потоке, вызывающий зависание в пользовательском интерфейсе

У меня есть долго работающая функция внутри асинхронной (последовательной) рабочей очереди. Я знаю, что иногда эта функция зависает внутри определенного вызова openCV. По какой-то причине это зависание также приводит к зависанию основного потока. При остановке и входе в режим отладки я вижу, что есть вызов

semaphore_wait_trap()

в главном потоке (Очередь)

Я могу приостановить зависание потока (Моя рабочая очередь) в режиме отладки, и затем эта ловушка исчезнет, ​​и графический интерфейс пользователя снова станет отзывчивым на телефоне.

После отмены приостановки рабочего потока графический интерфейс реагирует на 1-2 секунды (я подозреваю, что этот поток снова активируется), а затем пользовательский интерфейс снова перестает отвечать на запросы.

Эта тема не делает никаких dispatch_sync() звонки в основной поток / очередь

Возможно ли, что IOS приостанавливает основной поток ("перехватывает" его), потому что рабочий работает долго?

Могу ли я заставить его снять блок??

Я добавляю несколько экранов печати из стека режима отладки.

Прежде чем приостановить зависание очереди:

Стек основной очереди

И висящая нить:

Висячая очередь

И после приостановки и приостановки плохой очереди:

После приостановки

2 ответа

Возможно ли, что IOS приостанавливает основной поток ("перехватывает" его), потому что рабочий работает долго? - нет Я думаю, что ваша проблема связана с рисованием или изменением некоторых элементов пользовательского интерфейса. Не все функции могут быть вызваны из фонового потока (например, изменения в элементах пользовательского интерфейса должны быть сделаны в основном потоке.). В вашей последовательной очереди, если какой-либо метод должен изменить элементы пользовательского интерфейса, вы должны вызвать его в главном потоке, например:

dispatch_async(dispatch_get_main_queue(), ^{
                //do some main thread job here
            });
)

Возможно, вы просто забыли сохранить переменную в вызове функции dispatch (что касается меня, я опускал статическое ключевое слово перед объявлением dispatch_once_t, и диспетчеризация не может быть обработана встроенной функцией). Трассировка стека была такой же, как ваша. Это была моя вина.

+ (instancetype)sharedInstance
{
    (static was omitted) dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
} 
Другие вопросы по тегам