Swift 6 apareceu no WWDC 2024, e todos nós corremos para migrar todos os nossos aplicativos para isso … bem, na verdade não. Ficamos muito felizes com o que obtivemos no WWDC 2021 – a nova estrutura de simultaneidade estruturada do Swift 5.5 que nos ajudou a escrever um código seguro mais rapidamente com assíncrono/aguardar e atores. Swift 6 parecia quebrar tudo, e parecia uma boa ideia esperar um pouco.
Um ano depois, o caminho da migração parece muito mais suave, com muito mais guia. Continue lendo para descobrir o quanto isso se tornou mais fácil.
De thread único à simultaneidade
O objetivo do Swift 6.2 Concorrência é simplificar o desenvolvimento do seu aplicativo. Ele identifica três fases, onde você apresenta simultaneidade explicitamente, como e quando precisar:
- Execute tudo no tópico principal: Comece com a execução síncrona no thread principal – se todas as operações forem rápidas o suficiente, a interface do usuário do seu aplicativo não ficará pendurada.
-
assíncrono/aguardar: Se você precisar realizar uma operação lenta, criar e
await
umasync
função para fazer o trabalho. Esta função ainda é executada no tópico principal, que intercalados Seu trabalho com trabalho de outras tarefas, como responder à rolagem ou tocar do usuário. Por exemplo, se o seu aplicativo precisar baixar dados de um servidor, sua função assíncrona poderá fazer alguma configuração, em seguidaawait
umURLSession
Método que é executado em um encadeamento de segundo plano. Neste ponto, sua função suspende e o tópico principal é livre para fazer algum outro trabalho. Quando oURLSession
Método acaba, sua função está pronta para retomar a execução no thread principal, geralmente para fornecer alguns novos dados para exibir ao usuário. -
Simultaneidade: À medida que você adiciona mais operações assíncronas ao thread principal, a interface do usuário do seu aplicativo pode se tornar menos responsiva. Profile seu aplicativo com Instrumentos Para encontrar problemas de desempenho e ver se você pode corrigir o problema – acelere a operação lenta – sem simultaneidade. Caso contrário, introduza concorrência para mover essa operação para um tópico de fundo e talvez usar
async let
ou grupos de tarefas para executar subtarefas em paralelo para aproveitar as várias CPUs no dispositivo.
Domínios de isolamento
O Swift 6.2 Concorrência visa eliminar as corridas de dados, que ocorrem quando um processo em um thread modifica os dados enquanto um processo em outro thread está acessando esses dados. As corridas de dados só podem surgir quando seu aplicativo tem objetos mutáveis, e é por isso que Swift o encoraja a usar let
e tipos de valor como struct
tanto quanto possível.
As principais ferramentas para evitar corridas de dados são isolamento de dados e domínios de isolamento:
A característica crítica de um domínio de isolamento é a segurança que ele fornece. O estado mutável só pode ser acessado a partir de um domínio de isolamento por vez. Você pode passar o estado mutável de um domínio de isolamento para outro, mas nunca pode acessar esse estado simultaneamente a partir de um domínio diferente. Esta garantia é validada pelo compilador.
Existem três categorias de domínio de isolamento:
- Ator
- Ator Global
- Não isolado
Os atores protegem seus objetos mutáveis, mantendo uma fila em série para solicitações assíncronas provenientes de fora de seu domínio de isolamento. UM GlobalActor
deve ter uma propriedade estática chamada shared
Isso expõe uma instância do ator que você torna acessível globalmente – você não precisa injetar o ator de um tipo para outro ou no ambiente Swiftui.
De Abraçando a concorrência rápida:
O código não isolado é muito flexível, porque você pode chamá -lo de qualquer lugar: se você chamá -lo do ator principal, ele permanecerá no ator principal. Se você chamá -lo de um tópico de segundo plano, ele permanecerá em um thread de segundo plano. Isso o torna um ótimo padrão para bibliotecas de uso geral.
Isolamento de dados Garanta que entidades não isoladas não podem acessar o estado mutável de outros domínios, portanto, funções e variáveis não isoladas são sempre seguras para acessar de qualquer outro domínio.
Não isolado é o domínio padrão em swift.org porque o código não isolado não pode sofrer mutações protegidas em outro domínio. No entanto, novos projetos Xcode 26 terão MainActor
como o domínio de isolamento padrão, então Cada operação é executada no tópico principal A menos que você faça algo para mover o trabalho para um tópico em segundo plano. O tópico principal é serial, tão mutável MainActor
Os objetos podem ser acessados no máximo um processo por vez.
Migrando para Swift 6.2
Guia de migração swift.org
O Guia de migração rápida sugere um processo para migrar o código SWIFT 5 para Swift 6. Enquanto no modo Swift 5 Language, incrementalmente Ative Swift 6 verificando no seu projeto Construir configurações. Habilite essas configurações, uma de cada vez, em qualquer ordem, e resolva quaisquer problemas que surgirem:
Próximos recursos sugeridos pela estratégia de migração do Swift.org
No seu projeto Construir configuraçõesestes estão em Swift Compiler – Próximos recursos:
Próximas sugestões de recursos em configurações de construção do Xcode
Observação: Eu não vejo uma combinação exata para GlobalConcurrency
mas isso poder ser Variáveis globais isoladas.
Em seguida, ativar a verificação completa da concurência para ativar as verificações de isolamento de dados restantes. No Xcode, este é o Verificação estrita de simultaneidade configurando Swift Compiler – Concorrência.
Configurações do Xcode Build: Swift Compiler – Concorrência
Xcode 26 Configurações padrão
Novos projetos Xcode 26 terão essas configurações padrão para os outros dois Swift Compiler – Concorrência configurações:
- Concorrência acessível: Sim: Ativa um conjunto de recursos futuros que facilitam o trabalho com a simultaneidade.
-
Isolamento do ator padrão: Mainator: Código de isolados no
MainActor
A menos que você marque como outra coisa.
Habilitando Concorrência acessível Ativa vários Próximos recursosincluindo duas das sugestões de estratégia de migração do Swift.org:
Próximos recursos que a concorrência acessível permite
Se isso levantar muitos problemas, desative a simultaneidade acessível e tente a estratégia de migração swift.org.
Começando
Use o Download de materiais Botão na parte superior ou inferior deste artigo para baixar o projeto inicial e abra -o no Xcode 26 (beta).
Temet é um projeto de Aprendiz Swiftui. Ele procura O Museu Metropolitano de Arte, Nova York Para objetos que correspondem ao termo de consulta do usuário.
THEMET APP: Pesquise Persimmon
TheMetService
tem dois métodos:
-
getObjectIDs(from:)
constrói a consultaURL
e downloadsObjectID
Valores dos objetos de arte que correspondem ao termo da consulta. -
getObject(from:)
busca oObject
para um específicoObjectID
.
TheMetStore
instanciais TheMetService
e, em fetchObjects(for:)
chamadas getObjectIDs(from:)
Em seguida, faz um loop sobre a matriz de ObjectID
para preencher seu objects
variedade.
ContentView
instanciais TheMetStore
e chama isso fetchObjects(from:)
método quando aparece e quando o usuário insere um novo termo de consulta.
O aplicativo de amostra usa isso Thread
Extensão da postagem de Swiftlee Swift 6.2: uma primeira olhada em como está mudando de simultaneidade para mostrar quais tópicos fetchObjects(for:)
Assim, getObjectIDs(from:)
e getObject(from:)
estão funcionando.
nonisolated extension Thread {
/// A convenience method to print out the current thread from an async method.
/// This is a workaround for compiler error:
/// Class property 'current' is unavailable from asynchronous contexts;
/// Thread.current cannot be used from async contexts.
/// See: https://github.com/swiftlang/swift-corelibs-foundation/issues/5139
public static var currentThread: Thread {
return Thread.current
}
}
Neste tutorial, você migrará para a Swift 6.2 Concorrência.
Construa e corra e assista ao console:
Métodos de armazenamento e serviço em execução em threads de segundo plano
TheMetStore
e TheMetService
métodos são executados inteiramente em tópicos de segundo plano, exceto quando quando fetchObjects(for:)
Anexa um object
para objects
qual ContentView
displays. No entanto, no processo de desenvolvimento de aplicativos trifásicos da Swift 6.2, apenas o URLSession
O método precisa ser executado no encadeamento principal. Você logo consertará isso!