Tutoriel cacao pour les débutants
tablier
Membre
Par Miguel Saro
Débutant en programmation Cocoa et Objective-C, mais pas en programmation tout court, j'ai cherché à me documenter. J'ai d'abord trouvé la documentation d'Apple jointe à l'outil de developpement Xcode. INDISPENSABLE!!! mais extrêmement volumineuse et d'un emploi difficile pour un débutant. Je me suis inscris dans un forum sur Cocoa. Bonne chose! n'hésitez pas à vous inscrire dans un forum sur Cocoa.
J'ai donc pris la décision de bâtir un guide qui montre comment créer de bout en bout un projet "Objective-C / Cocoa" pour arriver à l'application terminée. J'ai pris comme point de départ le tutoriel "Currency Converter" d'Apple.
Vous pourrez télécharger ce tutoriel en cliquant ce lien: Tutoriel_Cacao
Le 10/03/2011. J'ai pris la décision de mettre à jour ce tutoriel. Cela va probablement me demander 1 ou 2 mois, alors soyez patients!
Débutant en programmation Cocoa et Objective-C, mais pas en programmation tout court, j'ai cherché à me documenter. J'ai d'abord trouvé la documentation d'Apple jointe à l'outil de developpement Xcode. INDISPENSABLE!!! mais extrêmement volumineuse et d'un emploi difficile pour un débutant. Je me suis inscris dans un forum sur Cocoa. Bonne chose! n'hésitez pas à vous inscrire dans un forum sur Cocoa.
J'ai donc pris la décision de bâtir un guide qui montre comment créer de bout en bout un projet "Objective-C / Cocoa" pour arriver à l'application terminée. J'ai pris comme point de départ le tutoriel "Currency Converter" d'Apple.
Vous pourrez télécharger ce tutoriel en cliquant ce lien: Tutoriel_Cacao
Le 10/03/2011. J'ai pris la décision de mettre à jour ce tutoriel. Cela va probablement me demander 1 ou 2 mois, alors soyez patients!
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ce tutoriel est destiné à des lecteurs ayant déjà une expérience de la programmation et qui souhaitent aborder Objective-C, Cacao et les outils de programmation associés, par le biais d'une prise en main pratique. Le tutoriel est basé sur la programmation effective d'une application complète par le lecteur.
Contenu du tutoriel (version 2.x):
(en gras les chapitres, et séparés par " / " les sections de chapitre)
Préambule
Introduction / Définition du projet
Création du projet Cacao et de son interface
Création du projet Cacao / Création de l'interface utilisateur / Définition de la classe CacaoControl /
Connexions CacaoControl - interface utilisateur / Définition des classes manquantes
Implémentation de Cacao
Generation des fichiers source / Déplacement des fichiers dans le groupe approprié /
Implémentation du Change / Premier essai, Débuggage
Amélioration du Change
Icône, Aide en ligne, Version, Information et 'A propos' / Sauvegarde des réglages / Corriger les défauts.
Implémentation, suite
Sélection d'une application / Obtenir sa version par applescript / Fenêtre d'alerte /
Sélection par glisser-déposer / Fermeture de la fenêtre (tagada tsoin tsoin)
Internationalisation
Rendre l'application localisable / Fichier nib / Textes / Chemin, Versions, Infos et nom de l'appli /
Fichier Crédits / Fichier d'aide
Objective-C, rappels
Méthodes et messages / Déclarations
Conclusions
Salut WIMP,
Regarde, tu as une nouvelle étoile...
J'avais supprimé en effet la partie Dev Ressources pdt la migration...
On télécharge ton tutorial en cliquant sur le 2.x...
merci pour ce tutorial très intéressant mais je tourne en rond là ....
D'où provient cet avertissement ?
2007-05-24 17:58:41.145 Cacao[5215] *** -[NSButton LaConversion:atRate:zero:Coef:]: selector not recognized [self = 0x3090d0]
A noter que j'ai essayé de débugger à coup de printf, LaConversion n'est jamais appelé et toutes les variables sont bien définies
j'ai beau retourner dans tous les sens le tutoriel, impossible de voir mon erreur ...
Merci d'avance
Un selecteur est l'identifiant (pour le compilateur) d'une méthode. Le selecteur en cause est "LaConversion:atRate:zero:Coef:". Si l'objet qui recoit le message ne connait pas ce selecteur tu recois effectivement le message pré-cité.
Ce qui m'étonne, c'est le "NSButton" à qui tu envois le message! Je ne me souviens pas d'avoir écrit cela!
Je viens de consulter le tutoriel, dans la méthode "a_Convertir" j'ai écris:
o_Convertir est l'IBOutlet qui permet d'acceder à l'objet Convertir qui contient la methode dont le selecteur est LaConversion:atRate:zero:Coef:
Après avoir refait divers trucs ...
Mmm, j'ai l'impression de retourner à mes débuts en programmation ...
bref, je sens que je vais devoir tout effacer et reprendre à 0... j'ai du rater une étape mais je me demande quoi.
Enfin bon, il faut encore le travailler...
Oui, enfin bon, l'histoire des majuscules, c'est un peu exagéré.
Certes beaucoup de développeurs utilisent cette "convention", mais ne pas respecter cela n'entraine pas une moins bonne compréhension du tutoriel.
Ah bon ?
Les méthodes "privées" sont généralement préfixées par un _ seul.
Enfin, faudrait déjà se mettre d'accord sur ce qu'est une méthode privée (en sens Obj-C où ce concept n'existe pas). Bref, ceci sort (une fois de plus) du cadre d'un tutoriel.
Pourtant, "typage statique" est le terme utilisé par Apple dans sa doc Obj-C (voir ici)...
Peut-être qu'Apple devrait lui aussi retravailler sa doc...
N'oublions pas que c'est un tutoriel.
L'objectif est de faire connaà®tre la prog en Obj-C et sous cocoa.
Donc, peu importe si l'auteur est "cool" sur les conventions et autres fioritures (qui sont souvent de l'encul... de mouche en plein vol).
Le principal reste que cela doit être à la portée du novice.
.
Apple, se réserve l'utilisation du préfixe '_' pour ses propres méthodes privées afin d'éviter que de nouveaux outils ajoutés par un développeur tierce n'écrasent des méthodes dont il ne connaà®trait pas l'existence...
Oui, Apple parle de typage statique dans sa doc... mais si tu lis un peu tu verras qu'il précise que les objets ont quand même liés dynamiquement à l'exécution.
C'est un tutoriel justement, et il ne doit pas donner des mauvaises habitudes ou de mauvaises indications, même et surtout si c'est pour un novice...
Merci pour ce petit débat sur ce tutoriel, et je dois préciser:
1) je ne suis pas informaticien, je me suis remis à la programmation en partant à la retraite.
2) j'ignorrais tout des conventions généralement utilisées par les programmeurs qui utilisent la POO et je ne connaissais rien de la POO!
3) je suis de l'avis de Bru: les conventions->boaf, ça change d'une entreprise à l'autre, d'une èpoque à l'autre...etc
4) néanmoins, je ne suis pas resté homogène par rapport à mes propres conventions (et c'est une erreur!)
5) je pense quand même (et vu le nombre de visiteurs) que globalement j'ai atteint mon objectif: permettre à des débutants en ObjC de prendre en main les outils d'Apple et avoir une idée de la programmation d'une application Mac et de ses différentes fonctionnalités
Dans le prochain tutoriel j'essaierai d'être plus constant dans le nommage des variables.
Son titre sera probablement: AppleScript, Cocoa et AppleEvents (Donc du script, de l'ObjC et du C-Carbon)
A+
J'ai souvent fait l'expérience, avec mon code ou celui d'autres qui m'entouraient, de codes sources qui, sur un même fichier, contenaient 15 conventions différentes avec seulement 5 personnes, tout simplement parce qu'on n'avait définit aucune convention au départ et qu'on ne tenait même nos propres conventions. Apple cherche sur ce point-là à donner des directives claires et simples pour que les programmeurs puissent écrire un code cohérent et qui ne les perturbent pas après 2 mois sans l'avoir lu.
Mais Apple cherche aussi à éviter les conflits entre les différents frameworks (les siens et ceux des autres), par exemple, dans le sous-classage d'une classe, on peut écrire des méthodes qui iront masquer des méthodes non-référencées dans l'interface et rendre la classe simplement inutilisable, comment prévenir ce genre de problème ?
Comment faire pour protéger des parties de codes masquées contre d'éventuels conflits ?
C'est sûr qu'on peut dire "oui les conventions, personne ne respecte les mêmes, les entreprises ne donnent aucune directive" etc. Il se trouve qu'Apple fait l'effort de donner des directives qui sont, selon moi, très pratiques et rendent le code beaucoup plus lisible en exploitant les noms à rallonge de l'Objective-C.
Donc tablier, je t'invite à lire ce document très intéressant sur la nomenclature en Objective-C : http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html
Ton code n'en sera que plus agréable à lire.
Dans la même catégorie, tu peux aussi lire les directives concernant l'interface utilisateur des applications Mac : http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGIntro/chapter_1_section_1.html
D'ailleurs Apple utilise parfois des majuscules quand la méthode commence par un sigle... Exemples :
Traduction : Pour les noms de méthodes, commencer avec une minuscule et une majuscule pour chaque mot contenu dans le nom. Ne pas utiliser de préfix.
Exemple donné : "fileExistsAtPath:isDirectory:".
Et qu'est-ce qui est dit juste en-dessous :
Traduction : Une exception à cette recommandation est le nom des méthodes commençant par un acronyme bien connu, par exemple, TIFFRepresentation (NSImage).
Donc il ne s'agit pas que d'une convention C++, mais bien aussi d'une convention Objective-C. Qui est d'ailleurs aussi respectée dans des projets comme GNUStep, à‰toilé SideStep.
Soit on définit quelque-chose et on s'y tient (en trouvant autre chose que de mettre bêtement le sigle au début), soit on ne fait rien...
Il se trouve que l'anglais est conçu comme ça, qu'est-ce qu'on peut y faire ?
Il faudrait pas non plus croire que l'informatique est parfaite, bien au contraire, c'est même l'endroit où on voit le plus d'ineptie... Ce genre d'exception sont juste un moindre mal...
getTIFFRepresentation, getUTF8String...
Dans les classes d'Apple, des fois on voit des "get" ("getData", "getIndexes"...), et des fois on n'en voit pas, c'est un peu l'anarchie ::)
Ce genre de "règle" (si définie en tant que règle) ne devrait pas avoir d'exception ; par exemple, si le compilateur était au courant des règles, ça ne passerait pas. C'est dans ce sens que les règles informatiques ne doivent pas souffrir d'exceptions, car un compilateur n'est en aucun cas laxiste.
Maintenant, je suis tout à fait d'accord qu'utiliser des minuscules c'est plus "propre", mais dans ce cas, il ne faut pas montrer le mauvais exemple :P
- les accesseurs "classiques" sont sans get (donc pas comme en Java).
Exemple : bounds de NSView
- les accesseurs avec get sont des methodes où l'on doit passer des adresses de variables pour récupérer plusieurs infos en même temps :
Exemple : getRed:green:blue:alpha: de NSColor.
(Je crois qu'il y avait déjà eu une discussion sur ce sujet ...)
Dans la section "Naming methods" du même document :
Traduction : Utiliser "get" seulement pour les méthodes qui retournent des objets et des valeurs indirectement. Vous ne devriez utiliser cette forme pour les méthodes uniquement lorsque plusieurs objets doivent être retournés.
L'exemple étant : - (void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;
Ce n'est donc utiliser que pour "retourner" des valeurs par références.
De plus, lorsque tu parles de faire vérifier les règles par un compilateur, ce qui est inutile puisque les noms sont uniquement utilisés pour permettre aux humains de comprendre plus facilement. Mais quand bien même ça le serait, il faut rappeler que les acronymes sont interdits par les conventions de nommages, à l'exception des "well-known acronyms", c'est-à -dire les acronymes bien connus comme TIFF, JPEG ou UTF8, dans tous les autres cas il n'est pas permis par la convention d'utiliser des acronymes. Il est donc tout à fait possible de programmer ton compilateur pour qu'il vérifie les mots permis.
Il suffirait de faire un dictionnaire de mots permis avec un attribut pour chacun disant si oui ou non il est sensible à la casse... Les acronymes seraient sensible à la casse, ainsi le compilateur n'accepterait que UTF8 et non pas utf8 ou UtF8, et pour les mots non sensibles à la casse, le compilateur n'accepterait la majuscule que sur la première lettre du mot et uniquement si le mot est précédé par un autre... C'est parfaitement envisageable. Les exceptions feraient alors pleinement parties de la règle.
D'ailleurs, les exceptions font toujours pleinement partie de la règle qu'elles accompagnent.
Une signature de fonction suffit largement à savoir qu'on utilise l'indirection ; c'est pas ajouter ou pas un "get" qui va changer grand chose...
Faut pas être rigide non plus :P D'ailleurs c'est pas très cohérent comme règle (ça met le trouble via une dissymétrie getters / setters).
Et si on n'utilise pas "get", on peut utiliser autre chose ; d'ailleurs "utf8String" est tout à fait envisageable (en minuscules, "utf8" est utilisé par MySQL par exemple).
De même que "tiffRepresentation" (les extensions sont en minuscules ; pourquoi pas ici ? On se croirait revenu au temps de Windows 3.1Â ???)
Quand aux acronymes interdit sauf les "well known", encore un truc débile ; qu'est-ce qu'un well-known ? Si j'écris un truc pour l'ONU ou le CNRS par exemple, qu'est-ce qui va m'empêcher de mettre "ONU" ou "CNRS" dans mes noms de méthode ("ah non, c'est pas well-known !"Â :fouf): )
Après l'histoire d'inclure l'exception dans le compilateur, ça me fait bien rire T'as déjà vu des compilateurs qui fonctionnent avec des règles à exceptions ? :P
C'est déjà suffisamment compliqué de définir une grammaire de langage pour en plus s'amuser à ajouter ce genre de choses...
Sérieusement, ça vous paraà®t pas chelou de voir ce genre d'exceptions dans des conventions de nommage ?Â
ça m'a toujours choqué et gêné ce "UTF8String"...
Vous avez déjà vu des conventions de nommage avec des exceptions de ce genre ? Je serais curieux de voir oùÂ :P
D'ailleurs on peut voir dans Objective-C qu'il y a quelques exceptions, par exemple, quand tu déclares une méthode dans une classe celle-ci doit être définie dans l'implémentation, mais lorsque tu déclares une méthode dans une catégorie, pas la peine de la définir.
Il y a aussi les catégories anonymes, on est censé nommer toutes les catégories mais il y a tout de même une exception qui concerne les catégories sans nom et les méthodes se doivent d'être définie dans la classe...
Si la plupart du temps dans un langage on cherche à éviter les exceptions c'est pour simplifier au maximum les parsers, mais outre la flemmardise qu'est-ce qui empêche d'ajouter ce genre de système.
Et je suis sûr que si on lisait la norme C en détail on verrait un tas d'exception dans tous les sens.
Personnellement je trouve les règles cohérentes, et arrête un peu ta mauvaise foi, les "well-known acronyms" sont les acronymes utilisés en informatique pour les différents types de fichiers ou d'encodage. Apple cherche surtout à éviter les notations hongroises qui sont une véritable plaie dans le codage ou les raccourcis de mots qui rendent les noms de méthodes illisibles...
Lis le document que j'arrête pas de référencer, tu verras que les règles sont cohérentes et qu'elles ont surtout pour but de permettre à tout codeur de lire facilement le code d'une autre personne... Et comme je l'ai dit plus tôt, ces règles ne sont pas seulement recommandées par Apple mais aussi par tous les autres développeurs Objective-C et ça depuis l'origine.
PS: tu reprochais plus haut qu'une des règles provenait du C++, après-tout, les get devant les méthodes c'est une règle du Java ou du C++, pas de l'Objective-C.
D'ailleurs, Apple n'utilise jamais le terme de getters/setters qui vient du C++/Java mais le terme de "accessors" (accesseurs), donc getters/setters est encore une déformation des autres langages.
Ainsi, par exemple en C on ne peut pas savoir si un argument passé en pointeur est à renseigner à l'appel avec une valeur, ou si ce paramètre est prévu pour faire un retour supplémentaire indirect de valeur. Donc là le "get" est bien pour lever définitivement les ambiguà¯tés. Au contraire je trouve que de ce côté les conventions qu'ont choisi Apple ont le mérite d'être assez carrées pour permettre de pas avoir d'ambiguà¯tés, et c'est très appréciable quand on les connait !
Et en Objective-C, dans le cas des méthodes pour les objets distribués, tu as les mots-clés "in", "out" et "inout", voire "oneway" permettant au compilateur de faire des optimisations.
Mais ce ne sont pas des exceptions ça, ce sont des règles ; une exception, ce sont des cas rares qui contredisent une règle.
Une méthode de classe et une méthode de catégorie c'est pas la même chose, alors que dire "les noms de méthodes doivent commencer par des minuscules, sauf...", là c'est une règle avec exception.
Après ça dépend de ce que t'appelles une exception... Si pour toi, le fait de pouvoir omettre les accolades quand il n'y a qu'une instruction c'est une exception, alors oui, il n'y a que des exceptions.
Non, désolé "Well-known acronyms" ça ne veut pas dire grand chose...
Tu m'en vois désolé si le fait que cette exception me choque te gène.
Et ils en usent et en abusent... MIME, URL, PDF, UTF, DOM, TIFF, EPS...
Dans ce cas c'est pas la peine de donner une convention de nommage :P
J'ai rarement vu du code avec des méthodes commençant par des majuscules à vrai dire...
Non, je reprochais le fait que la règle soit dévoyée, et que du fait ça n'était plus une règle ; nuance !
Pourtant, pour les propriétés, ils parlent bien de "getter" et "setter"
http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_5_section_3.html
Ainsi qu'ici par exemple :
http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_5_section_2.html
"Accessor" est un terme générique qui regroupe les deux.
Sisi, le mot clé "const" est là pour ça...
En plus du fait de savoir que les méthodes Cocoa ne laissent jamais à l'utilisateur le fardeau de devoir gérer la mémoire allouée (comme on voit dans beaucoup de bibliothèques C).
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html
PS : je ne vois pas le rapport entre la notation hongroise et le fait d'utiliser "UTF8" au lieu de "utf8"
J'ai bien réussi à générer l'application mais malgré tous mes efforts, j'ai décroché au niveau du chapitre "Spécifions la classe CacaoControl". Je ne suis pas sûr d'avoir compris son but. Ne peut-on pas s'en passer? Les objets ne peuvent-ils pas échanger entre eux sans passer par cette classe (si j'ai bien compris le fonctionnement du programme...)
"Spécifions la classe CacaoControl" existe dans le tutoriel d'origine d'Apple dont j'ai conservé (traduit et parfois modifié) un certain nombre de paragraphes.
A ce jour, un certain nombre de descriptions des méthodes de travail ne correspondent plus ou pas tout à fait à ce que l'on a sous Xcode3 et IB3, même si les principes restent. J'hésite beaucoup à reprendre la totalité du tutoriel car j'estime ce travail à un bon mois à plein temps!