Qu'est-ce que la délégation et pourquoi est-il important dans la programmation iOS?

11

En ce moment, j'enseigne moi-même la programmation iOS, et un concept que je trouve vraiment difficile à comprendre est la délégation. Qu'Est-ce que c'est? Pourquoi et comment est-il utilisé? Quel est l'avantage? L'écriture technique du livre que je lis est difficile à comprendre.

DCIndieDev
la source
4
Vous pouvez trouver utile l'intersection de balises déléguées c + délégués sur le débordement de pile utile.

Réponses:

16

Pour comprendre delegates, vous devez comprendre protocols.

A protocolest comme un contrat de service. Lorsqu'un objet (le plus souvent une UIViewControllersous - classe, mais pas toujours) signe ce contrat, il dit "Je suis intéressé à fournir une logique pour soutenir le message que vous m'envoyez". Cela est similaire NSNotificationCenteren ce qui concerne l'inscription à un niveau d'intérêt, la différence étant qu'un objet qui utilise la délégation ne peut en avoir qu'un delegateà la fois, alors que plusieurs objets peuvent s'inscrire pour le même NSNotification.

Apple utilise la délégation de manière omniprésente. De plus en plus, cependant, vous voyez Apple déplacer une grande partie de son API vers blocks, qui est similaire à callbacksdans d'autres langues.

Cela étant dit, la délégation aide à maintenir MVC, même si je dirais que la délégation est un modèle de conception en soi. Il aide à séparer les modèles des contrôleurs. Comme dans l'exemple de John Cartwright, a UITableViewsait afficher les lignes et les sections. Il sait comment réutiliser UITableViewCellspour des raisons de performances. Il connaît tous les autres trucs qu'il UIScrollViewconnaît. Mais il ne sait pas quelles cellules afficher. Il ne sait pas avec quoi remplir ces cellules. Il ne sait pas quelles cellules réutiliser pour une donnée NSIndexPath. De toute façon, cela devrait être le travail du contrôleur. La délégation permet à la vue de table de décharger cette logique de non-vue sur un objet qui devrait de toute façon avoir cette responsabilité.

De plus, vous n'êtes pas enfermé dans un seul délégué pendant toute la durée de vie d'un objet. Vous pouvez très facilement avoir plusieurs sources de données pour une donnée UITableViewet les changer au moment de l'exécution selon vos besoins.

Ainsi, d'une part, la délégation est idéale pour fournir des données et répondre aux interactions d'un objet. Vous verrez dans beaucoup de classes UIKit, un tel UITableView, UIPickerView, UICollectionView, etc.

Mais la délégation est également très utile lorsque vous souhaitez passer des informations entre des objets. Vous pouvez très facilement créer vos propres protocoles et enregistrer vos propres objets pour les suivre. De plus, les méthodes de protocole sont @requiredpar défaut, mais vous pouvez spécifier certaines méthodes@optional. Cela peut vous donner une belle flexibilité si vous en avez besoin. Disons que vous avez un contrôleur de vue parent et un contrôleur de vue enfant. Vous utilisez peut-être la nouvelle API de confinement pour ce faire. En règle générale, si vous devez transmettre des informations du parent à l'enfant, vous le faites avec une propriété. Terminé. Mais que faire si vous avez besoin de transmettre des informations de l'enfant au parent? Peut-être que quelque chose change chez l'enfant et que vous devez en informer le parent. Bien sûr, vous pouvez faire du KVO sur certaines valeurs. Mais vous voulez peut-être savoir quand un bouton est enfoncé. Créez simplement un nouveau protocole dans le contrôleur de vue enfant

@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end

@interface MyChildViewController : UIViewController

@property (weak, nonatomic) id <MyChildDelegate> delegate;

@end

Dans MyChildViewController, lorsque votre bouton est appuyé, vérifiez simplement si votre délégué répond au message du délégué (si cela est requis et que votre délégué n'implémente pas la méthode, vous planterez. Vous pouvez créer la méthode @optionalsi vous en avez besoin) et envoyer il:

- (IBAction)someButtonTapped:(id)sender {
    if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
        [self.delegate buttonWasTappedInChild:self];
    }
}

Ensuite, définissez le délégué de votre MyChildViewController selfet implémentez-le - (void)buttonWasTappedInChild:(MyChildViewController *)childViewControllerdans votre contrôleur de vue parent. BOOM! Vous avez des informations transmises d'un enfant au parent. La relation entre les deux objets n'a même pas besoin d'être aussi proche que parent / enfant. C'est un contrat de service, donc tant que la signature de l'objet tient le coup en mettant en place les méthodes requises, vous êtes en or!

REMARQUE: les délégués doivent être faibles / affecter des propriétés, sinon vous entrerez dans un cycle de rétention où aucun objet ne peut être désalloué.

J'espère que cela t'aides!

jmstone
la source
2

Les délégués sont des objets qui implémentent certaines fonctions lorsqu'il n'est pas logique d'implémenter ces fonctions sur l'objet normal. C'est une forme d'injection de dépendance.

Pour un exemple concret, regardez le protocole UITableViewDelegate. Ces méthodes n'ont aucun sens pour une vue de table à implémenter directement, car les actions de sélection d'une ligne de vue de table seront différentes dans chaque application et peut-être dans chaque vue de table. Le délégué dispose d'une méthode -tableView:didSelectRowAtIndexPath:qui vous permet de créer un objet qui gère la sélection de lignes sans sous-classer la vue de table pour chaque action distincte que vous souhaitez implémenter.

John Cartwright
la source