2009-11-08 2 views
4

Je sais que Objective-C utilise la liaison dynamique pour tous les appels de méthode. Comment cela est-il mis en œuvre? Est-ce que objective-c "se transforme en code C" avant la compilation et utilise simplement des pointeurs (void *) pour tout?Objective-C utilise la liaison dynamique, mais comment?

+3

L'exécution de l'objectif-c est open source, btw. Cela fait une lecture intéressante. objc_msgSend() est en fait un petit peu d'assemblage qui fait l'expédition en utilisant une optimisation de l'appel de queue pour éliminer le besoin de réécrire la trame de la pile lors de l'invocation. Tres rapide. – bbum

Répondre

11

Conceptuellement, ce qui se passe est qu'il ya une bibliothèque répartiteur (communément appelé l'objectif d'exécution C), et le compilateur convertit quelque chose comme ceci:

[myObject myMethodWithArg:a andArg:b ]; 

dans

//Not exactly correct, but close enough for this 
objc_msgSend(myObject, "myMethodWithArg:andArg:", a, b); 

Ensuite, le runtime traite toutes les liaisons et répartitions, trouve une fonction appropriée et l'appelle avec ces arguments. Simplement, vous pouvez penser à cela comme une recherche de hachage; bien sûr, c'est beaucoup plus compliqué qu'en réalité.

Il y a beaucoup plus de problèmes liés à des choses comme les signatures de méthodes (C ne code pas les types, donc le runtime doit y faire face).

4

Chaque méthode Objective C est implémentée "sous le capot" en tant que (en effet) une fonction C. La méthode a un message (chaîne de texte) qui lui est associé, et la classe a une table de recherche qui correspond à la chaîne de message avec la fonction C. Ainsi, lorsque vous appelez une méthode Objective C, ce qui se passe réellement, c'est que vous envoyez une chaîne de message à l'objet et que l'objet recherche la fonction C associée dans la table de recherche de méthode de sa classe et l'exécute. Objective C ne se limite pas à Objective C, comme la façon dont les objets gèrent les messages qu'ils ne comprennent pas en les transférant, comment ils mettent en cache les recherches de message à méthode, etc., mais ce sont les bases. C++ est similaire, sauf qu'au lieu de la classe ayant une table de message, il a quelque chose d'autre appelé "vtable", et vous invoquez une méthode non via une chaîne de texte, mais via son offset dans la vtable. C'est une forme de liaison statique, qui accélère quelque peu l'exécution, mais qui est moins flexible que la liaison dynamique.