Dans Objective C, vous avez le concept d'envoyer des messages à d'autres objets, et c'est très similaire à l'appel de méthode dans des langages comme C # et Java.
Mais quelles sont exactement les différences subtiles? Comment dois-je penser à la messagerie quand je pense à mon code?
Remarque: Juste un peu de contexte ici, je suis un développeur C # / Java essayant de comprendre certains concepts sur l'objectif C.
Réponses:
Un message est le nom d'un sélecteur et les paramètres de ce sélecteur.
Un sélecteur est un symbole.
Une méthode est un morceau de code dans une classe identifiée par un sélecteur.
En d'autres termes,
[foo bar: baz]
dit "envoyer le message appelé@selector(bar:)
avec le paramètrebaz
à l'objetfoo
. Vous pouvez envoyer ce message à de nombreux objets différents.En revanche, la méthode
bar:
pour unFoo
pourrait ressembler àmais pour un
FooTwo
pourrait ressembler(J'espère avoir la bonne syntaxe; cela fait un moment que je n'ai pas touché Objective-C pour la dernière fois.)
Lorsque vous envoyez le message, le noyau Objective-C envoie le message à
foo
qui décide s'il comprend le message. Il décide cela selon qu'il peut trouver une méthode identifiée par ce sélecteur.Deux méthodes avec le même nom et un message.
Il est également possible pour un objet de simplement transmettre un message particulier (ou un ensemble de messages) à un autre objet pour traitement. Dans ce cas, vous envoyez un message à cet objet proxy, qui n'a aucune méthode pour faire correspondre ce message , et le proxy transfère le message à son objet encapsulé.
la source
D'un point de vue purement théorique, il n'y a aucune différence entre les deux - il y a eu un certain nombre de preuves formelles montrant que les deux sont complètement équivalentes, et l'une ou l'autre peut être mise en œuvre entièrement en fonction de l'autre.
D'un point de vue légèrement moins théorique, il y a une différence possible: dans une implémentation typique, la table des fonctions virtuelles est allouée statiquement et le contenu de chaque table est fixé au moment de la compilation. La recherche de messages, en revanche, se fait généralement avec une sorte d'objet semblable à une carte, qui est généralement dynamique, ce qui signifie que vous pouvez le modifier au moment de l'exécution. Cela rend relativement facile l'ajout d'une nouvelle réponse à un message dans une classe existante. Malheureusement, dans la plupart des cas, cela reste principalement théorique. Tout d'abord, vous avez essentiellement affaire à du code auto-modifiable, ce que la plupart des gens ont décidé longtempsil y a longtemps. Deuxièmement, pour le rendre très significatif, vous devez à peu près être capable de compiler du nouveau code dans la classe existante pour répondre au nouveau message que vous supportez. Sans cela, tout ce que vous gagnez est la possibilité d'ajouter dynamiquement un nouveau nom pour une méthode existante.
Comme l'indique la fin du paragraphe précédent, d'un point de vue vraiment pratique, il y a très peu de différence entre les deux. Ce sont simplement deux (très légèrement) façons différentes de supporter la liaison tardive. Bien que la recherche basée sur les messages soit généralement un peu plus lente, il serait assez inhabituel que la différence soit vraiment significative. Dans la plupart des cas, ce ne sont que deux façons différentes d'accomplir la même chose.
la source
Dans Objective-C, les messages sont liés tardivement. Autrement dit, ils sont résolus au moment de l'exécution. C # prend en charge une construction similaire via le mot clé Dynamic qui déclare également qu'un objet est lié tardivement.
la source
Habituellement, les appels de méthode sont résolus au moment de la compilation (sauf si vous utilisez la réflexion en Java), tandis que les messages dans Objective C sont distribués au moment de l'exécution.
la source
struct
premier paramètre. Le bindung tardif est une partie essentielle du polymorphisme et donc de la POO.Les messages sont soit gérés par le noyau, soit par le langage lui-même (pour ObjC par exemple, il existe un très petit code assembleur qui le fait).
Dans le noyau linux par exemple, les messages sont faits avec des appels système / fonction: vous pouvez les trouver si vous cherchez sur la programmation système unix.
La principale différence entre un appel de méthode et un message est la suivante:
un appel de méthode ne se produit que dans votre code: dans ASM, il est traduit par un PUSH des arguments passés.
un message du noyau est principalement quelque chose envoyé au noyau qui est suivi et renvoyé à un certain processus. Je peux les confondre avec des pipes, mais peu importe: sachez qu'il existe déjà un mécanisme qui vous permet d'exécuter plusieurs programmes en même temps et de communiquer en même temps. Bien sûr, n'espérez pas que cela fonctionnera de la même manière sur Windows ou d'autres OS.
la source