Sobes.tech
Middle

O que é a contagem automática de links?

sobes.tech IA

Resposta da IA

A contagem automática de referências (Automatic Reference Counting, ARC) é um mecanismo de gestão de memória em Swift e Objective-C que rastreia e liberta automaticamente a memória atribuída aos objetos. Cada instância de classe tem um contador de referências que aumenta ao criar uma referência forte ao objeto e diminui ao removê-la. Quando o contador de referências chega a zero, o ARC desaloca automaticamente o objeto e liberta a memória que ocupa.

O ARC previne fugas de memória e liberações duplas, simplificando a gestão de memória em comparação com a gestão manual (como em Objective-C sem ARC).

Existem três tipos de referências:

  1. Strong (Forte): Aumenta o contador de referências do objeto. É o tipo de referência padrão.
  2. Weak (Fraca): Não aumenta o contador de referências. É usado para prevenir ciclos de referências fortes, quando dois objetos referenciam-se mutuamente. A referência fraca torna-se nil se o objeto apontado for desalocado. É definida com a palavra-chave weak.
  3. Unowned (Sem dono): Não aumenta o contador de referências e tem sempre um valor. É usado quando se sabe que a referência sempre apontará para um objeto enquanto este existir. Ao contrário de weak, a referência sem dono não se torna nil e pode causar uma falha se tentar aceder ao objeto após a sua desalocação. É definida com a palavra-chave unowned.

Exemplo de ciclo de referências fortes:

class Human {
    let name: String
    var apartment: Apartment? // Referência forte a um Apartment opcional
    init(name: String) {
        self.name = name
        print("\(name) está a ser inicializado")
    }
    deinit {
        print("\(name) está a ser desinicializado")
    }
}

class Apartment {
    let unit: String
    var tenant: Human? // Referência forte a um Human opcional
    init(unit: String) {
        self.unit = unit
        print("Apartamento \(unit) está a ser inicializado")
    }
    deinit {
        print("Apartamento \(unit) está a ser desinicializado")
    }
}

var john: Human?
var unit4A: Apartment?

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

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

john = nil
unit4A = nil
// Nenhum "John Appleseed está a ser desinicializado" nem "Apartamento 4A está a ser desinicializado" será exibido devido ao ciclo de referências fortes

Solução ao ciclo de referências fortes usando weak:

class Human {
    let 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 {
    let unit: String
    weak var tenant: Human? // 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: Human?
var unit4A: Apartment?

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

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

john = nil // John é desalocado, pois o seu contador de referências torna-se 0
unit4A = nil // Apartment é desalocado, pois o seu contador de referências torna-se 0