La méthode de dispatch est un algorithme utilisé pour sélectionner la méthode appropriée qui doit être invoquée lors d'un appel. L'objectif principal de la méthode de dispatch est de fournir au programme des informations sur l'endroit où il peut trouver le code exécutable d'une méthode spécifique en mémoire.
Les langages compilés ont trois types de méthode de dispatch :
Le dispatch statique est la méthode de dispatch la plus rapide dans Swift. Comme il n'y a pas de possibilité de surcharge de méthode, il n'existe qu'une seule implémentation de la méthode, et elle réside à un seul emplacement en mémoire.
\ Nous pouvons utiliser le dispatch statique en utilisant des mots-clés tels que static, final, private.
\ Le dispatch statique est la méthode de dispatch par défaut pour les types de valeur car les types de valeur ne peuvent pas être surchargés.
\ Examinons quelques exemples :
Une fois que nous ajoutons le mot-clé final à une classe, ses méthodes ne prennent pas en charge la surcharge, et c'est là que le dispatch statique entre en jeu.
// MARK: Final class final class ClassExample { // MARK: Static dispatch func method() { // implementation ... } }
Une fois que vous ajoutez une implémentation par défaut d'un protocole en utilisant une extension, sa méthode de dispatch passe au dispatch statique au lieu d'utiliser une Table Témoin.
// MARK: Prorocol Extension extension ProtocolExample { // MARK: Direct Dispatch func method() { // implementation ... } } class ClassExample2: ProtocolExample {} let classExample2 = ClassExample2() classExample2.method()
Lorsqu'une méthode est implémentée dans une extension, cela signifie qu'elle ne peut pas être surchargée par des sous-classes. Dans ce cas, il y a place pour le dispatch statique.
// MARK: Example Class Extension class ClassExample3 {} extension ClassExample3 { // MARK: Direct Dispatch func method() { // implementation ... } } let classExample3 = ClassExample3() classExample3.method()
Nous ne pouvons pas accéder à une méthode privée en dehors du corps de la classe. Cela signifie que la méthode ne peut pas être surchargée et utilise le dispatch statique.
// MARK: Access Control class ClassExample4 { // MARK: Direct Dispatch private func method() { // implementation ... } }
Le dispatch par table est utilisé lorsque nous devons traiter l'héritage. C'est un type de dispatch par défaut utilisé dans Swift.
Pour chaque instance d'une classe ou d'une sous-classe, une table virtuelle est créée qui contient des informations sur les méthodes implémentées pour chaque classe et stocke une référence à l'implémentation appropriée. Le principal inconvénient du dispatch par table virtuelle est qu'il a une vitesse inférieure au dispatch statique.
\ Examinons un exemple :
// MARK: Virtual Table class ParentClass { func method1() {} func methdod2() {} } class ChildClass: ParentClass { override func method1() {} func method3() {} }
\ Pour chaque instance, sa propre table virtuelle est créée comme suit :
\
Une Table Témoin est utilisée par les protocoles et est créée pour chaque classe qui se conforme au protocole. Le CPU utilise cette table pour déterminer où il doit chercher une implémentation appropriée. Chaque type (valeur et référence) qui se conforme à un protocole a sa propre Table Témoin de Protocole, qui contient des pointeurs vers les méthodes du type requises par le protocole.
\ Examinons un exemple :
// MARK: Witness Table Dispatch protocol ProtocolExample { func method1() func method2() } class ClassExample1: ProtocolExample { func method1() {} func method2() {} } class ClassExample2: ProtocolExample { func method1() {} func method2() {} }
\ Dans ce cas, une table témoin est créée pour chaque classe :
\
Le Dispatch par Message est le style de dispatch de méthode le plus dynamique. Il recherche une implémentation appropriée pendant l'exécution. Comme il fonctionne pendant l'exécution, nous pouvons utiliser le Method Swizzling pour changer les implémentations de méthodes.
\ Si vous voulez utiliser le dispatch par message, vous devez ajouter @objc dynamic avant une implémentation de méthode.
// MARK: Message Dispatch class ClassExample: NSObject { @objc dynamic func method() {} } class SubClassExample: ClassExample { @objc dynamic override func method() {} } let subclass = SubClassExample() subclass.method()
\ L'implémentation de la méthode est recherchée dans SubClassExample. S'il n'y a pas d'implémentation de cette méthode dans cette classe, la recherche continue dans la classe parente, et ainsi de suite jusqu'à ce qu'elle atteigne NSObject.
\
Combinons tous les types en un seul tableau :
\
En résumé, la méthode de dispatch dans Swift est un aspect critique de l'exécution du code, impactant les performances et la flexibilité. En choisissant la bonne méthode de dispatch, les développeurs peuvent optimiser leur code, assurer l'adaptabilité et exploiter efficacement les fonctionnalités dynamiques de Swift. Comprendre et maîtriser la méthode de dispatch est essentiel pour construire des applications Swift efficaces et adaptables.


