Swift e Objective-C

Síncrono vs. assíncrono, bloqueante vs. não bloqueante — Guia 2×2

O eixo síncrono/assíncrono indica quem acompanha a conclusão da tarefa, enquanto bloqueante/não bloqueante indica se o controle é devolvido imediatamente. Este guia explica por que os dois eixos independentes geram as quatro combinações 2×2, com exemplos em Swift.

5 min de leitura
Imagem de capa de Síncrono vs. assíncrono, bloqueante vs. não bloqueante — Guia 2×2

Eu entendo mais ou menos o síncrono e o assíncrono, mas tudo fica confuso quando entram bloqueante e não bloqueante.

No artigo relacionado Processo vs. thread: a principal pergunta de entrevista técnica, explicada pela estrutura de memória, você pode revisar os conceitos básicos e os casos de aplicação relacionados. Dispatch

Pode parecer que “síncrono = bloqueante e assíncrono = não bloqueante”, mas esses são eixos diferentes. Ao combiná-los, surgem quatro casos, e os quatro existem na prática.

Esses conceitos aparecem sempre que se fala de código de rede, async/await ou loops de eventos como os do Node.js. Depois que você entende bem os eixos, pode aplicar esse conhecimento muitas vezes.

Neste artigo, os dois eixos são diferenciados com precisão e as quatro combinações 2×2 são explicadas com exemplos.

Vamos começar pelo resumo principal.

  1. Eixo síncrono/assíncrono: quem acompanha a conclusão — é síncrono quando quem chama acompanha diretamente e assíncrono quando recebe uma notificação
  2. Eixo bloqueante/não bloqueante: se o controle é devolvido imediatamente após a chamada — se não é, é bloqueante; se é devolvido na hora, é não bloqueante
  3. Os dois eixos são independentes, portanto todas as 2×2 = 4 combinações existem
  4. Na prática, as duas combinações mais comuns são síncrono + bloqueante e assíncrono + não bloqueante

Eixo 1: Síncrono vs. assíncrono — quem acompanha a conclusão?

Síncrono significa que quem chama acompanha diretamente se uma tarefa foi concluída. Depois de enviar uma solicitação, o fluxo fica preso a essa tarefa até o resultado chegar.

Quando A termina, faça B; quando B termina, faça C. A ordem é garantida.

Assíncrono significa enviar uma solicitação, continuar outro trabalho e receber uma notificação quando ela termina. Callbacks, closures e continuations de async/await são esse “canal de notificação” (POSIX aio_read).

Pense em um restaurante. O síncrono é fazer o pedido e esperar no balcão até a comida ficar pronta.

O assíncrono é pegar um pager, fazer outra coisa na mesa e buscar a comida quando ele tocar.


Eixo 2: Bloqueante vs. não bloqueante — o controle é devolvido?

Agora a perspectiva é diferente. O critério é se a função chamada devolve o controle imediatamente.

Bloqueante significa que, depois da chamada, a thread que chamou fica presa até a função terminar. Nesse período, ela não pode fazer mais nada.

Não bloqueante significa que a chamada retorna imediatamente. Se o resultado ainda não estiver pronto, ela retorna pelo menos um status como “ainda não está pronto” (POSIX read).

Se síncrono/assíncrono descreve o “gerenciamento da conclusão”, bloqueante/não bloqueante descreve a “espera”. São eixos diferentes.


Todas as combinações 2×2

Diagrama das combinações 2×2 formadas pelos eixos síncrono/assíncrono e bloqueante/não bloqueante
Os dois eixos são independentes, portanto todas as quatro combinações existem
Combinação Comportamento Exemplo típico
Síncrono + bloqueante Esperar o resultado e continuar depois Chamada de função comum, leitura básica de arquivo
Síncrono + não bloqueante Retornar imediatamente e verificar repetidamente se está pronto (polling) Socket não bloqueante verificado continuamente em um loop
Assíncrono + bloqueante Esperar a notificação enquanto a thread permanece presa Iniciar uma API assíncrona e esperar imediatamente pelo resultado
Assíncrono + não bloqueante Disparar, fazer outra coisa e receber uma notificação quando terminar Callback de URLSession, async/await

O síncrono + não bloqueante pode parecer estranho: é como “um cliente que vai ao balcão a cada minuto perguntar ‘já ficou pronto?’ sem pager”.

Ele mantém o controle, mas acompanha a conclusão por conta própria; por isso é síncrono.

Assíncrono + bloqueante é, na prática, uma combinação desvantajosa. Se você torna algo assíncrono, mas espera imediatamente pelo resultado, não há diferença em relação a síncrono + bloqueante; apenas fica mais complexo.

Um exemplo é o código que chama wait assim que inicia uma função assíncrona.


No Swift

A terminologia sync/async da época do GCD (Grand Central Dispatch) está, na verdade, mais próxima de descrever se há bloqueio.

queue.sync prende a thread atual até a closure terminar (bloqueante). queue.async dispara o trabalho e passa imediatamente para a próxima linha (não bloqueante).

async/await é uma sintaxe que faz o código assíncrono + não bloqueante ser lido como código síncrono.

let data = try await fetchImage() // Aqui ocorre uma 'suspensão'
// A thread não fica bloqueada e vai fazer outro trabalho

No ponto await, a função pausa por um instante, mas a thread é liberada para processar outro trabalho. O código é lido de cima para baixo como código síncrono, embora seu comportamento real seja não bloqueante.

“Não bloquear a thread principal e ainda escrever sequencialmente sem o inferno dos callbacks” é o motivo de essa sintaxe existir.

Ilustração com uma estrada como metáfora: a função para em await, mas a thread continua seguindo
A função para em await, mas a thread é liberada para fazer outro trabalho

Pontos importantes para entrevistas

O primeiro passo é diferenciar os critérios dos dois eixos em uma frase para cada um.

“Bloqueante/não bloqueante diz respeito a devolver o controle imediatamente, enquanto síncrono/assíncrono diz respeito a quem chama acompanhar a conclusão ou receber uma notificação.”

Depois, para a pergunta de acompanhamento “dê um exemplo das quatro combinações”, basta apresentar um caso da tabela por vez. Saber explicar síncrono + não bloqueante (polling) é uma evidência especialmente forte de que você entendeu os eixos.


Resumo

  • Síncrono/assíncrono: é síncrono quando quem chama acompanha diretamente a conclusão e assíncrono quando recebe uma notificação
  • Bloqueante/não bloqueante: é bloqueante quando não devolve o controle na chamada e não bloqueante quando o devolve imediatamente
  • Os dois eixos são independentes, portanto todas as quatro combinações existem
  • Síncrono + não bloqueante é polling; assíncrono + bloqueante geralmente é uma combinação desvantajosa
  • O sync/async do GCD está mais próximo de descrever o bloqueio, enquanto async/await faz o código assíncrono + não bloqueante ser lido como código síncrono
  • Metáfora do restaurante: esperar no balcão (síncrono + bloqueante), perguntar a cada minuto (síncrono + não bloqueante) e usar um pager (assíncrono + não bloqueante)

Fontes e critérios de verificação

  • POSIX read — The Open Group · texto original do padrão/especificação · verificado em 2026-08-17 · base: E/S bloqueante e comportamento de O_NONBLOCK
  • POSIX aio_read — The Open Group · texto original do padrão/especificação · verificado em 2026-08-17 · base: solicitações de E/S assíncronas e modelos de conclusão
  • Dispatch — Apple · documentação oficial · verificado em 2026-08-17 · base: envio de tarefas síncronas e assíncronas baseado em filas