Às vezes ouvimos "Swift não faz GC clássico (rastreamento), ele usa ARC".
Mas não tenho certeza se há algo na semântica do Swift que exija contagem de referência. Parece que é possível criar o próprio compilador e tempo de execução Swift para usar o rastreamento de GC.
Então, o que exatamente é "contado por referência" sobre Swift? Implementação da Apple ou a própria linguagem? Existem partes do idioma ou da biblioteca que suportam tão fortemente o ARC que podemos usar esse rótulo para o próprio idioma?
fonte
deinit
como uma palavra-chave e sua semântica associada são realmente as coisas que colocam a contagem de referência diretamente no domínio da linguagem, e não na implementação.O chi respondeu à pergunta específica do corpo sobre o swift, essa resposta responde à pergunta mais geral do título.
o GC de contagem de referência e o GC de rastreamento fornecem ao programador garantias diferentes.
A contagem de referência fornece determinismo no local no fluxo do programa em que um objeto é destruído, que pode ser importante se o objeto possuir recursos escassos que devem ser liberados rapidamente. Por outro lado, não pode lidar com ciclos de referências "fortes".
Cabe à especificação de um idioma individual e se alguma característica é garantida e, portanto, quais opções estão disponíveis para uma implementação compatível.
fonte
Você pode pegar o idioma conhecido como Swift e renomeá-lo para "Swift with ARC". Você pode criar um novo idioma chamado "Swift with GC" com exatamente a mesma sintaxe, mas com menos garantias sobre quando os objetos são desalocados.
No Swift with ARC, quando a contagem de referência for 0, o objeto irá. Com a coleta de lixo, desde que você tenha uma referência fraca, você pode atribuir essa referência fraca a uma referência forte para "recuperar" o objeto. (No Swift, quando a contagem de referências é 0, as referências fracas são nulas); essa é uma grande diferença.
E é claro que o Swift with ARC garante que a eliminação da última contagem de referência desalocará o objeto imediatamente. Por exemplo, você pode ter uma classe FileWriter, na qual você não tem permissão para ter duas instâncias gravando no mesmo arquivo ao mesmo tempo. Em Swift with ARC, você poderia dizer oldWriter = nil; newWriter = FileWriter (...) e você saberia que o novo FileWriter é criado apenas após a exclusão do antigo (a menos que você tenha mantido outra referência); no Swift com GC isso não funcionaria.
Outra diferença é que, em "Swift with ARC", objetos que são referenciados apenas através de ciclos de referência fortes, mas que na verdade não são alcançáveis, têm garantia de não serem desalocados.
fonte