65 votes

Mécanisme d'envoi de messages Objective C

Je suis juste regarder jouer avec Objective C (écrit jouet applications de l'iPhone) et je suis curieux de connaître le mécanisme sous-jacent utilisé pour envoyer des messages. J'ai une bonne compréhension de la façon dont les fonctions virtuelles en C++ sont généralement mis en œuvre et les coûts par rapport à un statique ou non virtuelle d'un appel de méthode, mais je n'ai pas d'arrière-plan avec l'Obj-C pour savoir comment les messages sont envoyés. La navigation autour, j'ai trouvé ce lâche de référence et il mentionne IMP mise en cache des messages étant plus rapide que la fonction virtuelle appels, qui sont à leur tour plus rapide que d'envoyer un message standard.

Je ne suis pas en essayant d'optimiser quoi que ce soit, juste obtenir une compréhension plus profonde de la façon exacte dont les messages sont envoyés.

  • Comment sont-Obj-C les messages envoyés?
  • Comment puis-Méthode d'Instance Pointeurs de mise en cache et pouvez-vous (en général) dire en lisant le code, si un message de mise en cache?
  • Sont des méthodes de classe essentiellement la même qu'une fonction C (ou méthode de classe statique en C++), ou est-il quelque chose de plus?

Je sais que certaines de ces questions peuvent être "dépendant de l'implémentation", mais il y a seulement une mise en œuvre qui compte vraiment.

103voto

Alex Rozanski Points 26107

Comment sont-Obj-C les messages envoyés?

Objective-C les messages sont envoyés à l'aide du moteur d'exécution de l' objc_msgSend() fonction. Indiqué dans l' Apple docs, la fonction prend au moins 2 arguments:

  1. L'objet de réception
  2. Le sélecteur du message
  3. [Une liste variable d'arguments pour que le message soit envoyé.]

Les Instances d'une classe ont un isa pointeur, ce qui est un pointeur vers leur classe d'objet. Les sélecteurs de méthodes dans chaque objet sont stockés dans un "tableau" dans la classe de l'objet, et l' objc_msgSend() fonction suit l' isa pointeur vers la classe de l'objet, pour la trouver cette table, et vérifie si la méthode est décrite dans le tableau de la classe. Si il ne la trouve pas, il cherche la méthode dans le tableau de la classe de super-classe. Si pas trouvé, il se poursuit jusqu'à l'arborescence de l'objet, jusqu'à ce qu'il trouve la méthode ou à l'objet racine (NSObject). À ce stade, une exception est levée.

Comment puis-Méthode d'Instance Pointeurs de mise en cache et pouvez-vous (en général) dire en lisant le code, si un message de mise en cache?

D'Apple, Objective-C runtime guide sur la Messagerie:

Pour accélérer le processus de messagerie, le système d'exécution met en cache les sélecteurs et les adresses des méthodes comme ils sont utilisés. Il y a un cache distinct pour chaque classe, et il peut contenir des sélecteurs pour les méthodes héritées ainsi que pour les méthodes définies dans la classe. Avant de chercher l'envoi des tableaux, des messages de routine vérifie d'abord le cache de la réception de la classe de l'objet (sur la théorie qu'une méthode qui a été utilisée une fois peut probablement être utilisé à nouveau). Si le sélecteur de la méthode est dans le cache, la messagerie n'est que légèrement plus lent qu'un appel de fonction. Une fois qu'un programme a été en cours d'exécution assez longtemps pour "réchauffer" ses caches, presque tous les messages qu'il envoie à trouver une méthode mis en cache. Les Caches se développer de manière dynamique pour accueillir les nouveaux messages que le programme s'exécute.

Comme indiqué, la mise en cache commence à se produire une fois que le programme est en cours d'exécution, et après que le programme a été en cours d'exécution assez longtemps, la plupart des appels de méthode sera exécutée par le biais de la méthode mis en cache. Comme il est dit, la mise en cache se produit que les méthodes sont utilisées, de sorte qu'un message est mis en cache uniquement quand il est utilisé.

Sont des méthodes de classe essentiellement la même qu'une fonction C (ou méthode de classe statique en C++), ou est-il quelque chose de plus?

Les objets de la classe poignée de la méthode d'expédition dans une manière semblable à celle des instances de classes. Chaque objet de classe a un objet qui stocke sa propre classe de méthodes, dans un objet appelé un metaclass. L'objet de classe a sa propre isa pointeur vers son métaclasse objet, qui à son tour a des super métaclasse objets, il peut hériter de la classe des objets. Méthode d'expédition pour les méthodes de la classe est comme ça:

  1. Le système de répartition suit la classe de l'objet isa pointeur de la métaclasse objet
  2. La métaclasse méthode de l'objet table est recherchée pour la méthode de classe.
  3. Si pas trouvé, la recherche continue de la métaclasse de l'objet de la superclasse, où la recherche se poursuit.
  4. Ce processus se répète jusqu'à ce que la méthode est trouvé, ou jusqu'à ce qu'il arrive à la racine de la métaclasse, et une exception est levée.

19voto

bbum Points 124887

J'ai aussi écrit un guide d'instruction pour objc_msgSend () sur x86_64 sur mon blog, si quelqu'un souhaite plonger profondément:

http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/

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