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.
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.