Sobes.tech
Junior

O que é ARC (Contagem Automática de Referências) no iOS?

sobes.tech IA

Resposta da IA

O ARC é um mecanismo de gestão de memória no iOS que conta automaticamente as referências aos objetos. Quando o número de referências a um objeto chega a zero, o ARC liberta automaticamente a memória ocupada por esse objeto.

Vantagens do ARC:

  • Redução de fugas de memória: A automação do processo de libertação de memória reduz a probabilidade de erros relacionados com release ou dealloc esquecidos.
  • Redução de encerramentos inesperados devido a libertações duplas: O ARC impede tentativas de libertar memória que já foi libertada.
  • Simplificação do código: O programador não precisa de gerir manualmente a memória, tornando o código mais limpo e compreensível.

Apesar da automação, ao usar o ARC é importante compreender os conceitos de referências fortes e fracas para evitar ciclos de referências fortes (retain cycles).

Exemplo de referência forte:

class Person {
    var name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) está a ser inicializado")
    }

    deinit {
        print("\(name) está a ser desinicializado")
    }
}

class Apartment {
    var unit: String
    var tenant: Person? // Referência forte

    init(unit: String) {
        self.unit = unit
        print("Apartamento \(unit) está a ser inicializado")
    }

    deinit {
        print("Apartamento \(unit) está a ser desinicializado")
    }
}

var john: Person?
var unit4A: Apartment?

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

// Criação de uma referência forte de ambos os lados
john!.apartment = unit4A
unit4A!.tenant = john

// Nulificar referências não leva a deinit devido ao ciclo
john = nil
unit4A = nil

Exemplo de uso de referência fraca para quebrar o ciclo:

class Person {
    var name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) está a ser inicializado")
    }

    deinit {
        print("\(name) está a ser desinicializado")
    }
}

class Apartment {
    var unit: String
    weak var tenant: Person? // Referência fraca

    init(unit: String) {
        self.unit = unit
        print("Apartamento \(unit) está a ser inicializado")
    }

    deinit {
        print("Apartamento \(unit) está a ser desinicializado")
    }
}

var john: Person?
var unit4A: Apartment?

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

john!.apartment = unit4A
unit4A!.tenant = john

// Nulificar referências rompe o ciclo (deinit)
john = nil // Person desinicializado
unit4A = nil // Apartment desinicializado

O ARC aplica-se a objetos de classes. Estruturas e enumerações são tipos de valor e não estão sujeitos à gestão automática de memória pelo ARC.