51 votes

Objectif C: Blocs vs sélecteurs vs protocoles

Il m'arrive fréquemment de l'écriture de "l'utilité" des classes qui peuvent être ré-utilisés tout au long de mes projets.

Par exemple, supposons que j'ai un "Carnet d'Adresses". J'aimerais utiliser mon carnet d'adresses pour sélectionner envoyer un e-mail, ou peut-être qui s'ajoute à une demande de réunion.

Je développerai ce point de vue contrôleur de sorte qu'il peut être utilisé à la fois l'e-mail de contrôleur, et les réunions de contrôleur, avec une sorte de mécanisme de rappel à l'appelant de connaître l'utilisateur soit terminé de sélectionner quelqu'un à partir du carnet d'adresses, ou qu'ils ont annulé.

Il semble qu'il y a fondamentalement quatre (raisonnable) des approches on peut prendre dans ce scénario;

  • Créer un "AddressBookDelegate" protocole et d'un délégué de la propriété sur la AddressBookController. Ensuite, utilisez les messages définis dans le protocole pour communiquer le résultat (similaire à UIActionSheetDelegate).

  • Créer un "informelle" "AddressBookDelegate" protocole et d'un délégué de la propriété sur la AddressBookController, mais le type du délégué de la propriété sera "id", et de vérifier au moment de l'exécution avec "respondsToSelector:" pour voir si le délégué met en œuvre les méthodes que nous avons besoin (on dirait que la plupart de la cadre des trucs a commencé de cette façon).

  • Passer le AddressBookController un id qui représente un délégué, ainsi que de deux Corps qui préciser les méthodes à appeler lorsque l'utilisateur sélectionne un utilisateur ou annule la demande. L'avantage que je vois avec ce qui est; supposons que l'un contrôleur prend en charge à la FOIS de l'envoi de courriels ET l'organisation de rencontres (je sais que dans cet exemple, cela semble être une mauvaise conception... mais on peut imaginer une plus générique de la situation lorsque cela semble tout à fait raisonnable pour une classe utilitaire) - Dans ce cas, vous pourriez passer le AddressBookController différents SELs selon que vous êtes en train d'ajouter des utilisateurs à un courriel, ou ajouter des utilisateurs à une rencontre... une énorme amélioration par rapport à un iVar pour indiquer que le contrôleur "de l'état".

  • Passer le AddressBookController deux blocs, l'un à exécuter lorsque l'utilisateur sélectionne quelqu'un à partir du carnet d'adresses, et une autre si l'utilisateur annule la demande.

Les blocs ont été extrêmement utile pour moi, et de manière beaucoup plus élégante, je suis la recherche de moi-même presque confondus sur quand ne PAS les utiliser.

J'espère que des membres plus expérimentés de l'StackOverflow de la communauté que je peux les aider avec leurs réflexions sur ce thème.

27voto

Jared Pochtar Points 3240

Le "traditionnel" façon de le faire est avec un protocole. Informel ont été utilisés avant @protocole a été ajouté à la langue, mais c'était avant mon temps, et au moins pour les quelques dernières années informel protocoles ont été découragés, surtout compte tenu de l' @facultatif specifier. Comme pour un "délégué" qui passe les deux SELs, cela me semble plus laid que de déclarer un protocole formel, et en général ne semble pas juste pour moi. Les blocs sont de très nouveau (esp. sur iOS), que ces choses se passent, et alors que nous avons encore à voir l'énorme volume de la documentation/blogs sur le meilleur essayé et vrai style, j'aime bien l'idée, et cela semble être l'une des choses les blocs sont les meilleurs pour: neat nouveau flux de contrôle des structures.

Fondamentalement, ce que j'essaie de dire, c'est que chacune de ces méthodes varient en âge, avec aucun n'étant meilleure que la précédente, sauf pour le style, qui, évidemment, compte pour beaucoup, et, en définitive, pourquoi chacune de ces choses a été créé. Fondamentalement, aller avec le dernière chose que vous vous sentez à l'aise avec, qui devrait être de blocs ou d'un protocole formel, et que votre confusion est plus susceptibles de venir à partir de la lecture de sources contradictoires parce qu'ils ont été rédigés à des époques différentes, mais avec le temps, dans la perspective, il est évident de voir, qui annule et remplace les autres.

[Controller askForSelection:^(id selection){
  //blah blah blah
} canceled:^{
  //blah blah blah
}];

est probablement un enfer de beaucoup plus concis que la définition des deux méthodes supplémentaires, et un protocole pour eux (officiellement ou non), ou en passant le Corps et les stocker dans des ivars, etc.

17voto

kperryua Points 6905

Je voudrais juste aller avec votre première approche. C'est une essayé et vrai modèle dans le Cacao, et semble s'intègrent très bien dans ce que vous faites.

Quelques commentaires sur les autres approches:

  1. Informel protocole - je ne vois vraiment pas d'avantage de le faire sur un protocole officiel. Tous les depuis des protocoles officiels acquise @optional méthodes, l'utilité de l'informel protocoles est beaucoup moins.
  2. En passant SELs - je ne pense pas que ce soit un modèle établi dans le Cacao. Personnellement, je ne considère pas ça comme meilleur que le délégué de l'approche, mais si il s'adapte à votre façon de penser mieux, puis aller pour elle. Vous n'êtes pas vraiment se débarrasser de l'état; vous êtes juste en le transformant en quelque chose d'autre. Personnellement, je préfère avoir un ivar que je peux définir et de vérifier sans avoir à utiliser le sélecteur de types.
  3. En passant blocs - C'est une sorte de nouvel âge de la démarche, et il a un certain mérite. Je pense que vous devez être prudent parce que, à mon avis, il ne convient pas très bien. Par exemple, si NSTableView délégué de la source de données et méthodes ont été tous les blocs, je trouve personnellement qu'un peu ennuyeux. Imaginez si vous voulais mettre 10 différents blocs, votre -awakeFromNib (ou autre) méthode serait assez grand. Méthodes individuelles semble plus appropriée dans ce cas. Toutefois, si vous êtes sûr que vous n'allez pas aller au-delà de, disons, deux méthodes, le bloc approche me semble plus raisonnable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X