Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Le C est vraiment compatible avec Objective-C ? Tout ce que j'ai fait avec le tutoriel de M@teo je peux le faire en Objective-C sans rien changer ?
Oui ! Et mille fois oui ! Contrairement au C++ qui est un langage complètement différent inspiré du C. L'Objective-C est fait de C et de classes. Mais il faut tout de même apporter des modifications mineurs pour faire passer vos codes C pour du code Objective-C.
Déjà comme en C, on a deux types de fichiers : les fichiers sources ".c" et les fichiers d'en-tête (header) ".h". En Objective-C le fichier source devient un fichier ".m" au lieu de ".c" et le ".h" reste ce qu'il est.
Ensuite parmi les directives de précompilations comme #include, #define, #ifndef, etc. L'Objective-C ajoute la directive "#import". Cette directive est très pratique. En effet, elle remplace "#include" et permet, dans le fichier importé, de ne pas mettre les directives empêchant l'inclusion mutliple à savoir :
Code : C1
2
3
4
5
6 | #ifndef FICHIER_H_
#define FICHIER_H_
//déclarations
#endif
|
Vous n'en avez plus besoin !!! Le compilateur gère lui-même l'inclusion avec la directive "#import" et empêche de réinclure un fichier déjà importé sans ces directives.
L'Objective-C ajoute lui aussi son type booléen, il est un peu différent, il s'agit en fait du type "BOOL", et ses valeurs possibles sont "YES" (oui/vrai) et "NO" (non/faux), qui sont comme en C lorsqu'on définit un type booléen : NO = zéro et YES = tout sauf zéro. Sinon pour le reste tout est à peu prés pareil... En tout cas dans la programmation procédurale.
Les fonctions, les structures et les variables doivent toujours être déclarée avant d'être utilisées. Faites attention aux abus du C++. Vous ne pouvez pas notamment surcharger les opérateurs ni les fonctions normales.
La nomenclature est toujours la même, quand il y a plusieurs mots dans une variable on les identifie en mettant une majuscule à chacun d'eux, exemple : "maVariable", les noms des nouveaux types portent des majuscules au début. Les variables constantes sont en majuscule... vous pouvez bien sûr ne pas faire tout ça mais c'est conseillé...
Autre chose qui sera un peu plus importante au niveau de la programmation objet, c'est d'éviter les underscores "_" dans les noms des fonctions, il est préférable en effet de garder les majuscules pour les nouveaux mots plutôt que de mettre l'underscore à cause des conversions faites en interne par le compilateur... Mais je vous expliquerai ça plus tard

.
Donc voilà pour la programmation procédurale. La programmation procédurale est, au niveau du système, inchangé : une fonction est exécutée exactement de la même façon lors de son appel, c'est-à-dire qu'un espace lui est fourni dans la mémoire et les valeurs des arguments y sont copiées, etc. Vous aurez donc besoin des pointeurs, et ça à la pelle, vous pourrez vraiment pas faire sans, il n'y a pas de références comme en C++. Vous devrez même gérer la mémoire vous-mêmes, il n'y a pas de garbage collector comme en Java, mais ne vous inquiétez pas ce n'est pas particulièrement compliqué.
Alors voilà, le concept Objet, aujourd'hui très répandu, est comme en C++ ou Java et les autres, il a pour principe de réunir dans une unique structure homogène les données et les fonctions qui y sont attachées... Ça ne change pas ici

. En l'occurrence c'est plutôt la façon d'écrire une classe qui change. Mais avant de vous dire comment écrire une classe, je vais vous expliquer le concept central de la programmation en Objective-C.
Le Dynamisme
L'Objective-C est un langage entièrement dynamique. Il est basé sur un runtime (système d'exécution) qui permet de gérer les appels des messages, la création des objets, la communication entre eux... C'est ce qui a inspiré la machine virtuelle du Java, qui permet, pour le java, une portabilité totale : il faut juste avoir la machine virtuelle en question installée sur sa bécane

. En Objective-C, c'est à peu près pareil, mais si vous avez GCC d'installé sur votre machine (ce qui est le cas quand vous installez Xcode sur Mac), vous avez cette machine virtuelle.
Cependant, le runtime de l'Objective-C permet un dynamisme beaucoup plus fort qu'en Java, en laissant le soin au runtime d'exécuter telle ou telle méthode selon le contexte. En effet, en Objective-C, seul le runtime se soucit des types et des redirections, au pire le compilateur vous donne un warning, en effet, le type d'un objet n'est connu qu'à l'exécution.
On ne connaît pas le type au moment de la compilation ? Comment on fait quand on exécute la méthode d'un objet ? Comment on sait quel méthode on peut exécuter ?
Déjà je suppose que vous savez ce que vous faites donc vous connaissez les méthodes que vous pouvez exécuter sur un objet à tel moment. Mais à part ça, le type n'est pas directement connu à la compilation, il est possible d'indiquer quel est le type d'un objet, mais vous n'y êtes pas forcés et pour le compilateur ça ne changera pas grand chose. Comme je l'ai dit le compilateur vous dira au pire que l'objet ne pourra peut-être pas exécuter la méthode... Pas grand chose quoi

une simple supposition. Sinon c'est le runtime qui s'occupe de "reconnaître" un objet et de lui faire exécuter une méthode. C'est possible parce que chaque objet est capable de s'identifier, chaque objet est capable de dire au runtime à n'importe quel moment à quelle classe il appartient, quelle est sa classe mère et quelles méthodes il est capable d'exécuter.
Les Messages
Ce système est notamment permis par la métaphore du message. Ici, contrairement à ce que je dis depuis tout à l'heure, on n'appelle pas des méthodes mais on envoie un "message" à un objet. Pour le programmeur ça ne change strictement rien (sauf quand on l'écrit mais ça c'est une autre histoire

), si l'objet peut exécuter la méthode, elle est exécutée... En revanche, ce qui change des autres langages c'est que si l'objet n'en est pas capable soit l'objet redirige le message, soit le runtime laisse tomber l'exécution de la méthode

. Ça permet d'éviter de s'inquiéter pour des méthodes non gérées, dans la majorité des cas le programme continuera son exécution sans problème. Ici, le concept d'objet et de message est poussé au point que même les classes sont des objets : on les appelle "objets classe" et ils sont simplement identifiés par le nom de la classe lui-même. L'objet classe peut lui aussi recevoir des messages et exécuter des méthodes, mais il a surtout la capacité de créer de nouveaux objets de sa classe selon le modèle que vous lui avez fourni. Il alloue de la mémoire pour stocker l'objet et renvoie l' "instance" de la classe pour que vous puissiez l'utiliser. Cet objet peut à présent recevoir des messages comme les autres.
Et concrètement comment ça se passe ?
Il s'agit d'un système de redirection : quand on envoie un message à un objet, le runtime cherche dans les registres de l'objet pour voir si il peut exécuter la méthode et ensuite lui fait exécuter la méthode. En java, les messages ont été repris, mais là il faut connaître le type de l'objet à la compilation pour être capable de lui envoyer un message. Sachant qu'en ObjC vous n'avez pas besoin de connaître le type de l'objet pour lui envoyer un message, vous pouvez donc à ce moment définir des classes et des méthodes prennant un objet quelconque en argument et permettre d'autres programmeurs d'utiliser votre classe avec leurs propres objets ! C'est pratique, par exemple, pour les classes conteneurs comme les listes, les tableaux ou les dictionnaires.
Si la personne qui utilise votre classe veut utiliser certaines de ses capacités, il lui suffit de définir les méthodes utilisées par votre classe dans sa propre classe, de votre côté vous envoyez des messages à des objets sans types particuliers, l'objet répondra ou pas et vous modifierez le comportement selon le résultat. Je sais que ça a l'air banale comme ça... mais en fait, c'est très puissant et ça vous enlève quelques poids, vous n'avez pas besoin de classes génériques comme en C++ par exemple, vous n'avez pas non plus besoin de faire des casts sur les objets avant de leur envoyer un message comme en Java, on laisse au runtime le soin de connaître le type des objets et d'exécuter les méthodes.