У меня есть обратный вызов, который может прийти из любого потока. Когда я получаю этот обратный вызов, я хотел бы выполнить определенную задачу в главном потоке.
Нужно ли проверять, нахожусь ли я уже в главном потоке - или есть какой-либо штраф, если не выполнить эту проверку до вызова кода ниже?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Ответы:
Нет, вам не нужно проверять, находитесь ли вы уже в главном потоке. Отправляя блок в основную очередь, вы просто планируете последовательное выполнение блока в главном потоке, что происходит при выполнении соответствующего цикла выполнения.
Если вы уже находитесь в главном потоке, поведение такое же: блок запланирован и выполняется при запуске цикла выполнения основного потока.
источник
async
обратно в основную очередь, она будет запущена, но это может испортить ожидаемое время ваших действий . Такие , как код пользовательского интерфейса вviewDidLoad()
не работает до тех пор , после того, как сначала отображается вид .Для случая асинхронной отправки, который вы описали выше, вам не нужно проверять, находитесь ли вы в главном потоке. Как указывает Bavarious, он просто будет поставлен в очередь для запуска в главном потоке.
Однако, если вы попытаетесь выполнить вышеизложенное с помощью a
dispatch_sync()
и ваш обратный вызов находится в главном потоке, ваше приложение будет заблокировано в этот момент. Я описываю это в своем ответе здесь , потому что это поведение удивило меня при перемещении некоторого кода из-performSelectorOnMainThread:
. Как я уже упоминал, я создал вспомогательную функцию:который будет синхронно запускать блок в основном потоке, если метод, в котором вы находитесь, в данный момент отсутствует в основном потоке, и просто выполняет встроенный блок, если он есть. Вы можете использовать синтаксис, подобный следующему, чтобы использовать это:
источник
dispatch_set_specific()
, поможет ли это в случае, который вы описываете: stackoverflow.com/a/12806754/19679 .Как уже упоминалось в других ответах, dispatch_async из основного потока в порядке.
Однако, в зависимости от вашего варианта использования, есть побочный эффект, который вы можете рассматривать как недостаток: поскольку блок запланирован в очереди, он не будет выполняться до тех пор, пока управление не вернется в цикл выполнения, что приведет к задержке выполнение вашего блока.
Например,
Распечатает:
По этой причине, если вы ожидаете, что блок будет выполняться между внешними NSLog, dispatch_async не поможет вам.
источник
Нет, вам не нужно проверять, находитесь ли вы в главном потоке. Вот как вы можете сделать это в Swift:
Он включен в качестве стандартной функции в моем репо, проверьте его: https://github.com/goktugyil/EZSwiftExtensions
источник