Sobes.tech
Middle

À quoi sert le type de références unowned?

sobes.tech IA

Réponse de l'IA

Les références unowned sont nécessaires pour résoudre les cycles de référence (retain cycles) entre objets, lorsque les deux objets ont une référence forte l'un envers l'autre, mais qu'un des objets a un cycle de vie plus court ou égal à l'autre.

unowned est utilisé lorsque l'on sait que l'objet référencé ne sera pas nil pendant toute la durée de vie de l'objet contenant la référence. Contrairement à weak, l'accès à une référence unowned ne nécessite pas d'Optional. Si l'objet référencé par unowned est désalloué avant l'objet avec la référence unowned, cela provoquera un crash.

Exemple d'utilisation dans des closures :

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

    init(name: String) {
        self.name = name
        print("\(name) est en cours d'initialisation")
    }

    deinit {
        print("\(name) est en cours de désinitialisation")
    }
}

class Apartment {
    let unit: String
    // Utilisation de unowned car on sait que
    // l'Apartment ne peut pas exister sans Person
    // (dans ce contexte). Person peut être nil,
    // mais si l'Apartment existe, Person existe aussi.
    unowned let tenant: Person?

    init(unit: String, tenant: Person?) {
        self.unit = unit
        self.tenant = tenant
        print("Appartement \(unit) est en cours d'initialisation")
    }

    deinit {
        print("Appartement \(unit) est en cours de désinitialisation")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// Dans cet exemple, tenant peut être nil, donc
// on utilise une référence unowned optionnelle
unit4A = Apartment(unit: "4A", tenant: john)

john!.apartment = unit4A

// Rompons les références fortes pour tester la désallocation
john = nil
unit4A = nil

Dans cet exemple, Person a une référence forte à Apartment (var apartment: Apartment?). Apartment pourrait avoir une référence forte à Person, ce qui créerait un cycle. Cependant, dans ce contexte, Apartment ne peut exister sans Person (qui le loue), donc la référence de Apartment à Person est unowned. Ainsi, lorsque john est mis à nil, Person est désalloué, et par conséquent (puisqu'il n'y a pas de références fortes à Apartment), Apartment est également désalloué.

Principales différences avec weak :

  • Cycle de vie : unowned est utilisé lorsque l'objet référencé a un cycle de vie égal ou plus long. weak est utilisé lorsque l'objet référencé peut être désalloué plus tôt.
  • Optional : unowned n'est pas optionnel (sauf si déclaré comme unowned optional). weak est toujours optionnel.
  • Sécurité : Accéder à une propriété avec une référence unowned à un objet déjà désalloué provoquera un crash. Accéder à une référence weak renverra nil.

Ainsi, unowned est une référence non propriétaire (non-owning) utilisée lorsque la présence de l'objet référencé est garantie tant que l'objet contenant la référence existe.