Sobes.tech
Middle

Qu'est-ce que unowned?

sobes.tech IA

Réponse de l'IA

unowned — c'est un mot-clé en Swift pour déclarer une référence faible. Il est utilisé lorsque deux objets ont une relation forte et que leurs cycles de vie dépendent l'un de l'autre, mais que nous voulons éviter les références cycliques qui pourraient empêcher la libération de la mémoire.

Propriétés principales et différences avec weak :

  • Non optionnel : La référence unowned ne sera pas nil pendant toute la durée de vie de l'objet auquel elle fait référence.
  • Relation forte : Utilisée lorsque un objet possède un autre, et qu'ils existent toujours ensemble.
  • Lors de la libération : Si l'objet auquel la référence unowned fait référence est libéré de la mémoire avant que la référence ne soit utilisée, cela entraînera une erreur d'exécution (runtime error). Il faut s'assurer que l'objet référencé existe plus longtemps que la référence elle-même.
  • Application : Souvent utilisée pour les délégués, lorsque le délégué existe toujours plus longtemps que l'objet qui l'appelle, ou dans les closures pour éviter les références cycliques à self, lorsque la closure ne capture pas une référence forte à self.

Exemple d'utilisation dans une closure :

// swift
class MyClass {
    var name: String
    var closure: (() -> Void)?

    init(name: String) {
        self.name = name
    }

    func setupClosure() {
        closure = { [unowned self] in // Utilisation de unowned self
            print("Je m'appelle \(self.name)")
        }
    }

    deinit {
        print("\(name) désinitialisé")
    }
}

Exemple d'utilisation pour un délégué (bien que weak soit plus couramment utilisé pour les délégués, unowned est également possible si le délégué garantit de vivre plus longtemps) :

// swift
protocol MyDelegate: AnyObject { // AnyObject requiert un type de référence
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // référence `unowned` au délégué

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource désinitialisé")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

    override init() {
        super.init()
        dataSource = DataSource(delegate: self)
    }

    func doSomething() {
        print("Méthode du délégué appelée")
    }

    deinit {
        print("MyController désinitialisé")
    }
}

Le choix entre weak et unowned dépend de si la référence est optionnelle et si l'objet référencé existe garanti jusqu'à la fin de la vie de la référence. Si l'objet peut être libéré avant l'utilisation de la référence, il faut utiliser weak. Si la garantie de l'existence est assurée et que la référence ne doit pas être optionnelle, on peut utiliser unowned.