J'ai récemment acheté un Mac et l'utilise principalement pour le développement C # sous VMWare Fusion. Avec toutes les applications Mac de Nice, j'ai commencé à penser à Xcode caché à un clic d'installation et à l'apprentissage d'Objective-C.
La syntaxe entre les deux langages est très différente, sans doute parce que Objective-C a ses origines en C et que C # a ses origines en Java/C++. Mais différentes syntaxes peuvent être apprises, cela devrait donc être OK.
Ma principale préoccupation est de travailler avec la langue et de déterminer si elle aidera à produire un code bien structuré, lisible et élégant. J'apprécie vraiment les fonctionnalités telles que LINQ et var en C # et je me demande s'il existe des équivalents ou des fonctionnalités meilleures/différentes dans Objective-C.
Quelles fonctionnalités linguistiques vais-je manquer de développer avec Objective-C? Quelles fonctionnalités vais-je acquérir?
Edit: Les comparaisons de cadre sont utiles et intéressantes, mais une comparaison de langue est ce que cette question demande réellement (en partie de ma faute à marquant à l'origine avec .net
). Cacao et .NET sont vraisemblablement des frameworks très riches qui ont chacun leur raison d'être, l'un ciblant Mac OS X et l'autre Windows.
Merci pour les points de vue bien pensés et raisonnablement équilibrés jusqu'à présent!
Aucune langue n'est parfaite pour toutes les tâches, et Objective-C ne fait pas exception, mais il existe des subtilités très spécifiques. Comme avec LINQ
et var
(pour lesquels je n’ai pas connaissance de remplacement direct), certains d’entre eux sont strictement liés au langage et d’autres au framework.
(NOTE: Tout comme C # est étroitement associé à .NET, Objective-C est étroitement associé à Cocoa. Par conséquent, certains de mes arguments peuvent sembler sans rapport avec Objective-C, mais Objective-C sans Cocoa est semblable à C # sans .NET/WPF/LINQ, fonctionnant sous Mono, etc. Ce n’est tout simplement pas comme cela que les choses se passent habituellement.)
Je ne ferai pas semblant d'expliquer en détail les différences, les avantages et les inconvénients, mais voici quelques-unes de celles-ci.
L’un des aspects les plus intéressants d’Objective-C est la nature dynamique: au lieu d’appeler des méthodes, vous envoyez des messages que le moteur d’exécution achemine de manière dynamique. Combiné (judicieusement) à la dactylographie dynamique, cela peut simplifier, voire banaliser de nombreux modèles puissants.
En tant que sur-ensemble strict de C, Objective-C dit que vous savez ce que vous faites. Contrairement à l'approche gérée et/ou typée de langages tels que C # et Java, Objective-C vous permet de faire ce que vous voulez et d'en subir les conséquences. Évidemment, cela peut parfois être dangereux, mais le fait que le langage ne vous empêche pas activement de faire la plupart des choses est assez puissant. (EDIT: Je dois préciser que C # possède également des fonctionnalités et des fonctionnalités "non sécurisées", mais que leur comportement par défaut est le code géré, que vous devez explicitement désactiver. Par comparaison, Java seulement autorise le code de sécurité, et n'expose jamais les pointeurs bruts comme C et les autres le font.)
Les catégories (ajouter/modifier des méthodes sur une classe sans sous-classer ni avoir accès à la source) est une arme à double tranchant impressionnante. Cela peut grandement simplifier les hiérarchies d'héritage et éliminer le code, mais si vous faites quelque chose d'étrange, les résultats peuvent parfois être déroutants.
Cocoa simplifie la création d'applications graphiques à bien des égards, mais vous devez comprendre le paradigme. La conception de MVC est omniprésente dans Cocoa et les modèles tels que les délégués, les notifications et les applications à interface graphique à plusieurs threads conviennent parfaitement à Objective-C.
Les liaisons Cocoa et l'observation de la valeur clé peuvent éliminer des tonnes de code de colle, et les frameworks Cocoa l'exploitent largement. La répartition dynamique d'Objective-C va de pair avec cela, donc le type d'objet n'a pas d'importance tant qu'il est conforme à la clé-valeur.
Les génériques et les espaces de noms vous manqueront probablement, et ils ont leurs avantages, mais dans l’état d’esprit et le paradigme d’Objective-C, ils seraient plutôt des subtilités que des nécessités. (Les génériques concernent avant tout la sécurité des types et l’évitement des transtypages, mais le typage dynamique dans Objective-C en évite les problèmes. Les espaces de noms seraient bien s'ils étaient bien exécutés, mais ils sont assez simples pour éviter les conflits dont le coût est supérieur aux avantages, en particulier pour l'ancien code.)
Pour la simultanéité, les blocs (une nouvelle fonctionnalité de langage dans Snow Leopard et implémentée dans de nombreuses API Cocoa) sont extrêmement utiles. Quelques lignes (souvent associées à Grand Central Dispatch, qui fait partie de libsystem en 10.6) peuvent éliminer un nombre considérable de fonctions de rappel, de contexte, etc. (les blocs peuvent également être utilisés en C et C++, et pourraient certainement être ajoutés à C #, Ce qui serait génial.) NSOperationQueue est également un moyen très pratique d’ajouter des accès simultanés à votre propre code, en envoyant des sous-classes NSOperation personnalisées ou des blocs anonymes que GCD exécute automatiquement sur un ou plusieurs threads différents pour vous.
Je programme en C, C++ et C # depuis plus de 20 ans et a débuté en 1990. Je viens de décider de jeter un coup d'œil sur le développement de l'iPhone et de Xcode et Objective-C. Oh, mon Dieu… toutes les plaintes que je reprends à Microsoft, je réalise maintenant à quel point le code a été mauvais. Objective-C est trop complexe comparé à ce que fait C #. J'ai été gâté avec C # et j'apprécie maintenant tout le travail acharné de Microsoft. Il est difficile de lire juste Objective-C avec une méthode invoquée. C # est élégant en cela. C’est tout simplement mon opinion. J’espérais que le langage de développement Apple était aussi bon que les produits Apple, mais, mon cher, ils ont beaucoup à apprendre de Microsoft. Il n’est pas question que l’application C # .NET mette en place une application beaucoup plus rapidement que XCode Objective-C. Apple devrait certainement nous permettre de jeter un coup d’œil au livre de Microsoft 'aurais l'environnement parfait. :-)
Pas d'examen technique ici, mais je trouve que Objective-C est beaucoup moins lisible. Étant donné l'exemple que Cinder6 vous a donné:
C #
List<string> strings = new List<string>();
strings.Add("xyzzy"); // takes only strings
strings.Add(15); // compiler error
string x = strings[0]; // guaranteed to be a string
strings.RemoveAt(0); // or non-existant (yielding an exception)
Objectif c
NSMutableArray *strings = [NSMutableArray array];
[strings addObject:@"xyzzy"];
[strings addObject:@15];
NSString *x = strings[0];
[strings removeObjectAtIndex:0];
C'est affreux. J'ai même essayé de lire 2 livres dessus, ils m'ont perdu tôt, et normalement je ne comprends pas ça avec la programmation livres/langues.
Je suis heureux que nous ayons Mono pour Mac OS, car si je devais compter sur Apple pour me fournir un bon environnement de développement ...
La gestion manuelle de la mémoire est quelque chose que les débutants d’Object-C semblent avoir le plus de problèmes, principalement parce qu’ils pensent que c’est plus complexe qu’elle ne l’est.
Objective-C et Cocoa, par extension, reposent sur des conventions d’application; connaître et suivre un très petit ensemble de règles et vous obtenez beaucoup gratuitement par le temps d'exécution dynamique en retour.
La règle pas vraie à 100%, mais assez bonne pour tous les jours est:
alloc
doit être associé à un release
à la fin de la portée actuelle.alloc
, elle doit être renvoyée par return [value autorelease];
au lieu d'être jumelé à un release
.L'explication la plus longue suit.
La gestion de la mémoire est basée sur la propriété. niquement le propriétaire d'une instance d'objet doit toujours libérer l'objet, tout le monde sinon, ne doit toujours rien faire. Cela signifie que dans 95% de tout le code, vous traitez Objective-C comme s'il s'agissait d'ordures collectées.
Alors qu'en est-il des 5% restants? Vous avez trois méthodes à surveiller: toute instance d'objet reçue de cette méthode appartient à la portée de la méthode actuelle :
alloc
new
ou newService
.copy
et mutableCopy
.La méthode propose trois options possibles quant à l'utilisation des instances d'objet lui appartenant avant la fermeture:
release
s'il n'est plus nécessaire.autorelease
.Alors, quand devriez-vous vous approprier de façon proactive en appelant retain
? Deux cas:
Bien sûr, si tout ce que vous avez vu dans votre vie est l’objectif C, sa syntaxe semble la seule possible. Nous pourrions vous appeler une "programmation vierge".
Mais comme beaucoup de code est écrit en C, C++, Java, JavaScript, Pascal et d'autres langages, vous verrez qu'ObjectiveC est différent d'eux, mais pas dans le bon sens. Ont-ils une raison pour cela? Voyons d'autres langues populaires:
C++ a ajouté de nombreux extras à C, mais il a modifié la syntaxe d'origine uniquement selon les besoins.
C # a ajouté de nombreux extras par rapport au C++, mais il ne modifiait que les choses qui étaient laides en C++ (comme supprimer le "::" de l'interface).
Java a changé beaucoup de choses, mais il a gardé la syntaxe habituelle, sauf dans les parties où la modification était nécessaire.
JavaScript est un langage complètement dynamique qui peut faire beaucoup de choses que ObjectiveC ne peut pas. Néanmoins, ses créateurs n’ont pas inventé une nouvelle façon d’appeler des méthodes et de passer des paramètres pour se différencier du reste du monde.
Visual Basic peut transmettre des paramètres dans le désordre, tout comme ObjectiveC. Vous pouvez nommer les paramètres, mais vous pouvez également les transmettre de la manière habituelle. Quoi que vous utilisiez, tout le monde comprend ce qui est délimité par des virgules. La virgule est le séparateur habituel, pas seulement dans les langages de programmation, mais aussi dans les livres, les journaux et le langage écrit en général.
La syntaxe de Object Pascal est différente de celle de C, mais sa syntaxe est en réalité plus facile à lire pour le programmeur (peut-être pas pour l'ordinateur, mais qui se soucie de ce que pense l'ordinateur). Alors peut-être qu'ils ont digressé, mais au moins leur résultat est meilleur.
Python a une syntaxe différente, qui est encore plus facile à lire (pour les humains) que Pascal. Donc, quand ils ont changé, en le rendant différent, au moins ils l'ont rendu meilleur pour nous, les programmeurs.
Et puis nous avons ObjectiveC. Ajoutant quelques améliorations à C, mais inventant sa propre syntaxe d’interface, appel de méthode, passage de paramètre et tout le reste. Je me demande pourquoi ils n'ont pas échangé + et - de sorte que plus soustrait deux nombres. Cela aurait été encore plus cool.
Steve Jobs a foiré en supportant ObjectiveC. Bien sûr, il ne peut pas supporter C #, ce qui est meilleur, mais appartient à son pire concurrent. Il s’agit donc d’une décision politique et non d’une décision pratique. La technologie souffre toujours lorsque les décisions techniques sont prises pour des raisons politiques. Il devrait diriger la société, ce qu’il fait bien, et laisser la programmation aux véritables experts.
Je suis sûr qu'il y aurait encore plus d'applications pour iPhone s'il décidait d'écrire iOS et de prendre en charge des bibliothèques dans un autre langage que ObjectiveC. ObjectiveC semble ridicule, moche et répugnant à tous, sauf aux inconditionnels, aux programmeurs vierges et à Steve Jobs.
Une des choses que j'aime dans object-c, c'est que le système d'objet est basé sur des messages, il vous permet de faire de belles choses que vous ne pouviez pas faire en C # (du moins tant qu'elles ne prennent pas en charge le mot-clé dynamique!).
Interface Builder est un autre atout majeur dans l’écriture d’applications cacao. Il est bien plus sympathique que le concepteur de formulaires de Visual Studio.
Les choses à propos de obj-c qui me gênent (en tant que développeur C #) sont le fait que vous devez gérer votre propre mémoire (il y a une récupération de place, mais cela ne fonctionne pas sur l'iPhone) et qu'il peut être très prolixe à cause de la syntaxe de sélecteur et tous les [].
En tant que programmeur débutant avec Objective-C pour iPhone, issu du C # 4.0, il me manque les expressions lambda, et en particulier Linq-to-XML. Les expressions lambda sont spécifiques à C #, tandis que Linq-to-XML est vraiment un contraste .NET vs Cocoa. Dans un exemple d'application que j'écrivais, j'avais du XML dans une chaîne. Je voulais analyser les éléments de ce XML dans une collection d'objets.
Pour ce faire dans Objective-C/Cocoa, je devais utiliser la classe NSXmlParser . Cette classe repose sur un autre objet qui implémente le protocole NSXMLParserDelegate avec des méthodes appelées (lecture: messages envoyés) quand une balise open element est lue, quand certaines données sont lues (généralement à l'intérieur de l'élément), et quand une balise de fin d'élément est lue. Vous devez suivre l'état et l'état de l'analyse. Et honnêtement, je n'ai aucune idée de ce qui se passe si le code XML est invalide. C'est génial pour entrer dans les détails et optimiser les performances, mais oh mec, c'est beaucoup de code.
En revanche, voici le code en C #:
using System.Linq.Xml;
XDocument doc = XDocument.Load(xmlString);
IEnumerable<MyCustomObject> objects = doc.Descendants().Select(
d => new MyCustomObject{ Name = d.Value});
Et voilà, vous avez une collection d'objets personnalisés tirés de XML. Si vous vouliez filtrer ces éléments par valeur, ou uniquement ceux contenant un attribut spécifique, ou si vous ne vouliez que les 5 premiers, ou ignorer le premier 1 et obtenir les 3 suivants, ou simplement savoir si des éléments ont été renvoyés ... BAM, tout droit là dans la même ligne de code.
Il existe de nombreuses classes open-source qui facilitent beaucoup ce traitement dans Objective-C, ce qui facilite grandement les tâches lourdes. Ce n'est tout simplement pas intégré.
* NOTE: Je n'ai pas réellement compilé le code ci-dessus, il s'agit simplement d'un exemple illustrant le manque relatif de verbosité requis par C #.
La différence la plus importante est probablement la gestion de la mémoire. Avec C #, vous obtenez un ramasse-miettes, du fait qu’il s’agit d’un langage basé sur CLR. Avec Objective-C, vous devez gérer vous-même la mémoire.
Si vous venez d’un contexte C # (ou de tout langage moderne), passer à un langage sans gestion automatique de la mémoire sera très pénible, car vous passerez beaucoup de temps à coder à gérer correctement la mémoire (et à bien).
Voici un très bon article comparant les deux langues: http://www.coderetard.com/2008/03/16/c-vs-objective-c/