Sobes.tech
Middle

Quels sont les types de références en Swift?

sobes.tech IA

Réponse de l'IA

En Swift, il existe trois principaux types de références:

  1. **Référence Forte (Strong Reference):

    • Augmente le compteur de références de l'objet.
    • Empêche la déallocation de l'objet tant qu'au moins une référence forte existe.
    • C'est le type de référence par défaut en Swift.
    • La principale cause de cycles de références fortes.
  2. **Référence Faible (Weak Reference):

    • N'augmente pas le compteur de références.
    • Permet la déallocation de l'objet s'il n'y a plus de références fortes.
    • Déclarée avec le mot-clé weak.
    • Toujours optionnelle (Optional), car l'objet référencé peut devenir nil.
    • Utilisée pour prévenir les cycles de références fortes, lorsqu'une instance peut exister indépendamment d'une autre.
    class Person {
        let name: String
        weak var apartment: Apartment? // Référence faible
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) désalloué") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Référence forte normale
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Appartement \(unit) désalloué") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Ici, un cycle de références fortes sans weak
    
    // Les références sont annulées, les objets sont désalloués
    john = nil
    unit4A = nil
    
  3. **Référence Non Propre (Unowned Reference):

    • N'augmente pas le compteur de références.
    • Permet la déallocation de l'objet s'il n'y a plus de références fortes.
    • Déclarée avec le mot-clé unowned.
    • N'est pas optionnelle. On suppose que l'objet référencé existera toujours tant que l'instance contenant la référence non propre existe.
    • Utiliser une référence non propre sur un objet déjà désalloué entraînera une erreur à l'exécution (crash).
    • Utilisée pour prévenir les cycles de références fortes, lorsque une instance doit toujours exister tant qu'une autre existe, et qu'il n'y a pas de possibilité que l'un devienne nil indépendamment de l'autre (par exemple, dans les captures self dans les closures).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) désalloué") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Référence non propre
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Carte #\(number) désallouée") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Si le client est annulé, la carte qui y fait référence avec unowned,
    // deviendra invalide, mais ne causera pas de cycle.
    john = nil // Les deux objets sont désalloués
    

Le choix entre weak et unowned dépend de la nature de la relation entre les objets : utilisez weak lorsque un objet peut exister sans l'autre (Person sans Apartment), et unowned lorsque un objet doit toujours exister tant que l'autre existe (CreditCard appartient toujours à Customer).