Что такое QoS, для чего он используется и какие бывают приоритеты в iOS
Что проверяют
Понимаете ли вы, что приоритет в iOS назначается не потоку, а работе, и умеете ли выбирать класс осознанно. За вопросом стоит умение не сваливать всё на очередь по умолчанию и не ронять плавность интерфейса тяжёлой фоновой задачей.
Как отвечать
QoS (Quality of Service) это обещание системе, для чего нужна работа. По нему планировщик раздаёт процессорное время, приоритет ввода-вывода, склеивает таймеры и выбирает, на каких ядрах считать. Это классификация задачи, а не число у потока.
Классы по убыванию:
- userInteractive: то, от чего зависит кадр на экране, анимация и реакция на жест. Бюджет миллисекунды.
- userInitiated: пользователь нажал и ждёт результата, счёт на секунды.
- default: значение, которое подставляется, если ничего не указали.
- utility: долгая работа с видимым прогрессом, загрузка или импорт.
- background: то, о чём пользователь не знает, синхронизация и индексация; система откладывает такую работу при низком заряде и нагреве.
Класс задаётся очереди или конкретной задаче: DispatchQueue.global(qos: .utility), DispatchQueue(label: "import", qos: .utility). В Swift Concurrency то же самое выражает TaskPriority.
Сильный ответ добавляет распространение приоритета: если поток с высоким классом ждёт результат через sync или блокировку, система поднимает класс исполнителя, чтобы не получить инверсию приоритетов.
Где спотыкаются
Говорят, что QoS это про фоновые задачи. Класс есть у любой работы, включая ту, что идёт на главном потоке, а default не фоновый: он просто значение по умолчанию между userInitiated и utility.
Помечают высоким классом всё подряд, чтобы работало быстрее. Если приоритет одинаковый у всего, приоритетов нет, а заряд расходуется зря: система перестаёт отличать кадр анимации от выгрузки логов.
Путают класс очереди с потоком. Обновление интерфейса всё равно обязано уйти на главную очередь, userInteractive на фоновой очереди не делает её главной и не спасает от гонок.