Intern
O que é um coletor de lixo (garbage collector)?
sobes.tech IA
Resposta da IA
No iOS, é utilizado o ARC (Contagem Automática de Referências) — um mecanismo de contagem automática de referências que não é um coletor de lixo tradicional. Em vez de escanear a memória periodicamente, o ARC gere automaticamente a memória inserindo chamadas a retain, release e autorelease no código durante a compilação.
Princípio de funcionamento do ARC:
- Cada objeto tem um contador de referências.
- Ao criar um objeto ou atribuir uma referência forte, o contador aumenta (
retain). - Ao definir uma referência forte para nil ou sair do escopo, o contador diminui (
release). - Quando o contador chega a zero, o objeto é liberado da memória.
Vantagens do ARC:
- Liberação de memória determinista (sabe-se quando um objeto será removido).
- Sem pausas relacionadas ao coletor de lixo tradicional.
- Alto desempenho.
Desvantagens do ARC:
- Referências cíclicas ( ciclos de retenção) podem causar vazamentos de memória se não forem usadas referências fracas (
weak) ou não possuídas (unowned).
Exemplo de referência cíclica e sua solução:
class Person {
let name: String
var apartments: [Apartment] = [] // Referência forte ao Apartment
init(name: String) { self.name = name }
deinit { print("\(name) está sendo desalojado") }
}
class Apartment {
let unit: String
weak var tenant: Person? // Referência fraca ao Person
init(unit: String) { self.unit = unit }
deinit { print("Apartamento \(unit) está sendo desalojado") }
}
// Criando uma referência cíclica
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john?.apartments.append(unit4A!)
unit4A?.tenant = john
// Atribuir a nil não liberta a memória devido ao ciclo
john = nil
unit4A = nil
// Nenhuma mensagem de deinit será exibida
// Solução usando referência fraca
class FixedPerson {
let name: String
var apartments: [FixedApartment] = []
init(name: String) { self.name = name }
deinit { print("\(name) está sendo desalojado") }
}
class FixedApartment {
let unit: String
weak var tenant: FixedPerson? // Referência fraca ao Person
init(unit: String) { self.unit = unit }
deinit { print("Apartamento \(unit) está sendo desalojado") }
}
var fixedJohn: FixedPerson? = FixedPerson(name: "John Appleseed")
var fixedUnit4A: FixedApartment? = FixedApartment(unit: "4A")
fixedJohn?.apartments.append(fixedUnit4A!)
fixedUnit4A?.tenant = fixedJohn
// Atribuir a nil agora liberta a memória
fixedJohn = nil
fixedUnit4A = nil
// As mensagens de deinit serão exibidas
Ao contrário dos coletores de lixo tradicionais (por exemplo, em Java ou Python), que pausam a execução do programa para procurar e liberar objetos não utilizados, o ARC funciona de forma mais eficiente e previsível no contexto do desenvolvimento móvel.