Sobes.tech
Intern

O que é um coletor de lixo (garbage collector)?

sobes.tech IA

Resposta da IA

No iOS, não há um coletor de lixo tradicional. Em vez disso, é utilizado o mecanismo de Referência Automática (ARC).

  • Mecanismo automático: O ARC conta automaticamente as referências fortes aos objetos.
  • Liberação de memória: Quando o número de referências fortes a um objeto chega a zero, o ARC libera a memória alocada.
  • Prevenção de fugas: O uso correto de referências fortes, fracas e não possuídas (unowned) permite prevenir fugas de memória e ciclos de referências fortes.

Tipos de referências no ARC:

  • Forte (strong): Aumenta o contador de referências. É o padrão.
  • Fraca (weak): Não aumenta o contador de referências. Torna-se automaticamente nil ao desalocar o objeto. Usada para prevenir ciclos de referências fortes. Declarada como um tipo opcional.
  • Não possuída (unowned): Não aumenta o contador de referências. Garante que o objeto referenciado existe durante toda a vida útil da referência não possuída. Não é opcional. Usada quando dois objetos têm uma relação forte mútua, mas um deles tem um ciclo de vida mais curto.

Vantagens do ARC:

  • Previsibilidade: A liberação de memória ocorre de forma determinista, assim que o objeto não é mais utilizado.
  • Desempenho: Não há custos adicionais de coleta de lixo em segundo plano, que podem causar pausas.
  • Simplicidade: O desenvolvedor não precisa gerenciar manualmente a memória na maioria dos casos, mas deve entender os princípios de contagem de referências para evitar fugas.

Exemplo de ciclo de referências fortes:

class Person {
    let name: String
    var apartment: Apartment? // referência forte a 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 a Person para prevenir ciclo

    init(unit: String) { self.unit = unit }
    deinit { print("Apartamento \(unit) está sendo desalojado") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john // O uso de weak aqui é crítico

john = nil
unit4A = nil
// Sem tenant weak: Tanto john quanto unit4A não seriam desalojados.
// Com tenant weak: Tanto john quanto unit4A são desalojados corretamente.