Sobes.tech
Junior

Como funciona o coletor de lixo (garbage collector)?

sobes.tech IA

Resposta da IA

No contexto do desenvolvimento iOS/macOS, Swift/Objective-C não utiliza um coletor de lixo (GC), mas sim a contagem automática de referências (Automatic Reference Counting, ARC).

O ARC gere automaticamente a memória contando o número de referências fortes a cada instância de classe (e fechamentos com captura). Quando o contador de referências fortes chega a zero, o sistema libera a memória ocupada pelo objeto.

Pontos principais do ARC:

  • Referências fortes (Strong): Aumentam o contador de referências. O objeto permanece na memória enquanto houver pelo menos uma referência forte.
  • Referências fracas (Weak): Não aumentam o contagem de referências. São usadas para evitar ciclos de referências fortes. Apontam para um objeto opcional, que se torna nil quando o objeto é liberado.
  • Referências não possuídas (Unowned): Não aumentam o contador de referências. São usadas quando se conhece o ciclo de vida dos objetos e um objeto sempre existirá enquanto outro existir. A referência não é opcional. Se o objeto referenciado por um unowned for liberado, uma tentativa de acesso causará um erro em tempo de execução.

O ARC funciona na fase de compilação, inserindo chamadas a retain (aumentar o contador) e release (diminuir o contador) no código correspondente.

class MyClass {  
    var prop: String = ""  
}

var reference1: MyClass? = MyClass() // Contador = 1
var reference2 = reference1 // Contador = 2

reference1 = nil // Contador = 1
reference2 = nil // Contador = 0, o objeto é liberado
class Person {  
    let name: String
    weak var apartment: Apartment? // Referência fraca para evitar ciclo
    init(name: String) { self.name = name; print("\(name) está sendo inicializado") }
    deinit { print("\(name) está sendo desinicializado") }
}

class Apartment {  
    let unit: String
    unowned var tenant: Person // Referência não possuída
    init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Apartamento \(unit) está sendo inicializado") }
    deinit { print("Apartamento \(unit) está sendo desinicializado") }
}