Sobes.tech
Middle+

Qu'est-ce qui viole la fonction optionnelle dans le protocole?

sobes.tech IA

Réponse de l'IA

Ajouter des exigences au protocole après que d'autres modules ou bibliothèques ont commencé à l'utiliser. Si le protocole a déjà été adopté et implémenté, ajouter des méthodes ou propriétés optionnelles (non obligatoires) entraînera des erreurs de compilation partout où le protocole est utilisé, jusqu'à ce que ces nouvelles exigences soient satisfaites.

Les exigences optionnelles permettent d'étendre les protocoles sans "casser" les implémentations existantes. Les classes ou structures peuvent implémenter seulement une partie des méthodes optionnelles. Cela est utile lors du travail avec des délégués ou lors de l'ajout de nouvelles fonctionnalités à une API déjà établie.

Exemple d'exigence optionnelle dans un protocole en Objective-C (car Swift ne supporte pas @optional sans @objc) :

// En Swift, `@optional` est utilisé avec `@objc protocol`
import Foundation

@objc protocol MyDelegate {
    func requiredMethod() -> Bool

    @optional func optionalMethod1()
    @optional func optionalMethod2(value: Int)
}

class MyClass {
    weak var delegate: MyDelegate?

    func doSomething() {
        if delegate?.requiredMethod() == true {
            // Appel d'une méthode optionnelle avec vérification
            delegate?.optionalMethod1?()

            if let delegate = delegate {
                if delegate.responds(to: #selector(delegate.optionalMethod2(value:))) {
                    delegate.optionalMethod2?(value: 10)
                }
            }
        }
    }
}

En Swift, les protocoles purs (sans @objc) ne supportent pas @optional. Pour avoir des exigences optionnelles, le protocole doit être marqué comme @objc. Les implémentations de ces protocoles peuvent utiliser des extensions pour ajouter des implémentations par défaut des méthodes optionnelles, ce qui est une approche plus moderne en Swift.

Exemple de comportement optionnel via des extensions de protocoles en Swift :

// Approche plus Swift : extensions de protocoles avec implémentation par défaut
protocol MyProtocol {
    func requiredMethod() -> Bool
    func optionalMethod1()
    func optionalMethod2(value: Int)
}

// Fournir des implémentations par défaut pour les méthodes "optionnelles"
extension MyProtocol {
    func optionalMethod1() {
        // Implémentation par défaut vide ou comportement standard
        print("Implémentation par défaut de la méthode optionnelle 1")
    }

    func optionalMethod2(value: Int) {
        // Implémentation par défaut vide
        print("Implémentation par défaut de la méthode optionnelle 2 avec valeur : \(value)")
    }
}

class MyClassSwift {
    var delegate: MyProtocol?

    func doSomething() {
        if delegate?.requiredMethod() == true {
            // Appeler les méthodes sans vérification de nil, car
            // elles sont soit implémentées dans la classe/structure, soit utilisent
            // l'implémentation de l'extension
            delegate?.optionalMethod1()
            delegate?.optionalMethod2(value: 20)
        }
    }
}

class MyCustomDelegate: MyProtocol {
    func requiredMethod() -> Bool {
        print("Méthode requise implémentée")
        return true
    }

    // optionalMethod1() et optionalMethod2(value:) ne sont pas obligatoires à implémenter,
    // l'implémentation par défaut de l'extension sera utilisée.
    // Mais elles peuvent être redéfinies si un comportement différent est souhaité :
    // func optionalMethod1() {
    //     print("Implémentation personnalisée de la méthode optionnelle 1")
    // }
}

let customDelegate = MyCustomDelegate()
let myClassSwift = MyClassSwift()
myClassSwift.delegate = customDelegate
myClassSwift.doSomething()

Ainsi, ajouter une fonction optionnelle dans un protocole viole la compatibilité rétroactive si vous essayez d'ajouter une nouvelle exigence obligatoire à un protocole déjà utilisé dans la base de code. L'utilisation d'exigences optionnelles (via @objc ou, de préférence, via des extensions de protocoles) évite cette violation.