Ich habe kürzlich einen Mac gekauft und verwende ihn hauptsächlich für die C # -Entwicklung unter VMWare Fusion. Mit all den netten Mac-Anwendungen habe ich angefangen, über Xcode nachzudenken, der nur einen Klick entfernt lauert und Objective-C lernt.
Die Syntax zwischen den beiden Sprachen sieht sehr unterschiedlich aus, vermutlich weil Objective-C seinen Ursprung in C hat und C # seinen Ursprung in Java / C ++ hat. Es können jedoch verschiedene Syntaxen gelernt werden, so dass dies in Ordnung sein sollte.
Mein Hauptanliegen ist die Arbeit mit der Sprache und ob sie dazu beitragen wird, gut strukturierten, lesbaren und eleganten Code zu erstellen. Ich mag Funktionen wie LINQ und var in C # sehr und frage mich, ob es in Objective-C Entsprechungen oder bessere / unterschiedliche Funktionen gibt.
Welche Sprachfunktionen werde ich bei der Entwicklung mit Objective-C vermissen? Welche Funktionen werde ich gewinnen?
Bearbeiten: Die Framework-Vergleiche sind nützlich und interessant, aber ein Sprachvergleich ist das, was diese Frage wirklich stellt (teilweise meine Schuld für das ursprüngliche Markieren mit .net
). Vermutlich sind sowohl Cocoa als auch .NET sehr umfangreiche Frameworks für sich und beide haben ihren Zweck, eines für Mac OS X und das andere für Windows.
Vielen Dank für die gut durchdachten und einigermaßen ausgewogenen Standpunkte!
quelle
Antworten:
Keine Sprache ist perfekt für alle Aufgaben, und Objective-C ist keine Ausnahme, aber es gibt einige sehr spezifische Besonderheiten. Wie bei der Verwendung von
LINQ
undvar
(für die mir kein direkter Ersatz bekannt ist) sind einige davon streng sprachbezogen, andere rahmenbezogen.( HINWEIS: So wie C # eng mit .NET verbunden ist, ist Objective-C eng mit Cocoa verbunden. Daher scheinen einige meiner Punkte nicht mit Objective-C verbunden zu sein, aber Objective-C ohne Cocoa ähnelt C # ohne .NET / WPF / LINQ, läuft unter Mono usw. Es ist einfach nicht die Art und Weise, wie Dinge normalerweise gemacht werden.)
Ich werde nicht vorgeben, die Unterschiede, Vor- und Nachteile vollständig zu erläutern, aber hier sind einige, die mir in den Sinn kommen.
Einer der besten Teile von Objective-C ist die dynamische Natur. Anstatt Methoden aufzurufen, senden Sie Nachrichten, die die Laufzeit dynamisch weiterleitet. In Kombination (mit Bedacht) mit dynamischer Typisierung kann dies die Implementierung vieler leistungsfähiger Muster vereinfachen oder sogar trivial machen.
Als strikte Obermenge von C vertraut Objective-C darauf, dass Sie wissen, was Sie tun. Im Gegensatz zum verwalteten und / oder typsicheren Ansatz von Sprachen wie C # und Java können Sie mit Objective-C tun, was Sie wollen, und die Konsequenzen erfahren. Natürlich kann dies manchmal gefährlich sein, aber die Tatsache, dass die Sprache Sie nicht aktiv daran hindert, die meisten Dinge zu tun, ist ziemlich mächtig. ( BEARBEITEN: Ich sollte klarstellen, dass C # auch "unsichere" Features und Funktionen hat, aber das Standardverhalten ist verwalteter Code, den Sie explizit deaktivieren müssen. Im Vergleich dazu lässt Java nur typsicheren Code zu und macht niemals rohe Zeiger verfügbar so wie C und andere.)
Kategorien (Hinzufügen / Ändern von Methoden zu einer Klasse ohne Unterklasse oder Zugriff auf die Quelle) sind ein fantastisches zweischneidiges Schwert. Es kann Vererbungshierarchien erheblich vereinfachen und Code eliminieren. Wenn Sie jedoch etwas Seltsames tun, können die Ergebnisse manchmal verwirrend sein.
Cocoa macht das Erstellen von GUI-Apps in vielerlei Hinsicht viel einfacher, aber Sie müssen sich mit dem Paradigma auseinandersetzen. MVC-Design ist in Cocoa allgegenwärtig, und Muster wie Delegaten, Benachrichtigungen und GUI-Apps mit mehreren Threads eignen sich gut für Objective-C.
Durch Kakaobindungen und die Beobachtung von Schlüsselwerten können Tonnen von Klebercode eliminiert werden, und die Cocoa-Frameworks nutzen dies in großem Umfang. Der dynamische Versand von Objective-C geht Hand in Hand damit, sodass der Typ des Objekts keine Rolle spielt, solange er den Schlüsselwerten entspricht.
Sie werden wahrscheinlich Generika und Namespaces vermissen, und sie haben ihre Vorteile, aber in der Objective-C-Denkweise und im Paradigma wären sie eher Feinheiten als Notwendigkeiten. (Bei Generika dreht sich alles um Typensicherheit und das Vermeiden von Casting, aber dynamisches Tippen in Objective-C macht dies im Wesentlichen zu keinem Problem. Namespaces wären nett, wenn sie gut gemacht würden, aber es ist einfach genug, um Konflikte zu vermeiden, bei denen die Kosten die Vorteile überwiegen, insbesondere für Legacy-Code.)
Bei gleichzeitiger Verwendung sind Blöcke (eine neue Sprachfunktion in Snow Leopard, die in zahlreichen Cocoa-APIs implementiert ist) äußerst nützlich. Ein paar Zeilen (häufig gekoppelt mit Grand Central Dispatch, das Teil von libsystem unter 10.6 ist) können erhebliche Rückschläge bei Rückruffunktionen, Kontext usw. beseitigen. (Blöcke können auch in C und C ++ verwendet werden und können sicherlich zu C # hinzugefügt werden. Das wäre fantastisch.) NSOperationQueue ist auch eine sehr bequeme Möglichkeit, Ihrem eigenen Code Parallelität hinzuzufügen, indem Sie entweder benutzerdefinierte NSOperation-Unterklassen oder anonyme Blöcke versenden, die GCD automatisch für Sie in einem oder mehreren verschiedenen Threads ausführt.
quelle
alloca
. Es macht sie einfach nicht so leicht zugänglich - Sie müssen sich explizit anmelden.Ich programmiere jetzt seit über 20 Jahren in C, C ++ und C #, angefangen 1990. Ich habe mich gerade entschlossen, mir die iPhone-Entwicklung sowie Xcode und Objective-C anzuschauen. Oh mein Gott ... all die Beschwerden über Microsoft, die ich zurücknehme, ich merke jetzt, wie schlimm Code war. Objective-C ist im Vergleich zu C # überkomplex. Ich wurde mit C # verwöhnt und jetzt schätze ich die harte Arbeit, die Microsoft geleistet hat. Nur das Lesen von Objective-C mit Methodenaufrufen ist schwer zu lesen. C # ist dabei elegant. Das ist nur meine Meinung, ich hoffte, dass die Apple-Entwicklungssprache so gut ist wie die Apple-Produkte, aber meine Liebe, sie können viel von Microsoft lernen. Keine Frage, C # .NET-Anwendung Ich kann eine Anwendung um ein Vielfaches schneller als XCode Objective-C zum Laufen bringen. Apple sollte hier auf jeden Fall ein Blatt aus Microsofts Buch herausnehmen, und dann hätten wir die perfekte Umgebung. :-)
quelle
"Just reading Objective-C with method invokes is difficult to read"
- Hier ist nur ein sehr subjektives Argument, das hier als Nachteile von Obj-C erwähnt wird. Alles andere ist nur umstrittene Rhetorik.Keine technische Überprüfung hier, aber ich finde Objective-C viel weniger lesbar. Anhand des Beispiels, das Cinder6 Ihnen gegeben hat:
C #
Ziel c
Es sieht schrecklich aus. Ich habe sogar versucht, 2 Bücher darüber zu lesen, sie haben mich früh verloren, und normalerweise verstehe ich das nicht mit Programmierbüchern / Sprachen.
Ich bin froh, dass wir Mono für Mac OS haben, denn wenn ich mich auf Apple verlassen müsste, um mir eine gute Entwicklungsumgebung zu bieten ...
quelle
[NSMutableArray array]
stattdessen mit enden sollte (er verliert Speicher) und die 4. Zeile mitNSString* x
oder beginnen sollteid x
(Kompilierungsfehler) ... Ja, Objective-C fehlen Generika (ich vermisse sie ehrlich gesagt nicht), Sie tun es nicht Indizieren Sie keine Objekte mit Array-Syntax, und die APIs sind im Allgemeinen ausführlicher. To-may-to, to-mah-to. Es kommt wirklich darauf an, was Sie lieber sehen. (Sie könnten denselben Code in C ++ STL schreiben, und ich würde ihn für abscheulich halten.) Lesbarer Code bedeutet für mich oft, dass der Text des Codes Ihnen sagt, was er tut, und daher ist der Objective-C-Code vorzuziehen.List<T>.Remove
eine Zeichenfolge als Argument verwendet wird und das erste Auftreten dieser Zeichenfolge entfernt wird. Zum Entfernen nach Index benötigen SieRemoveAt
.removeObjectAtIndex:
, obwohl ausführlicher, auch eindeutig ist, was sie tut.strings[0]
undstrings.RemoveAt(0)
beeinträchtigt die Klarheit, zumindest für mich. (Außerdem nervt es mich immer, wenn Methodennamen mit einem Großbuchstaben beginnen ... Ich weiß, dass es ein kleines Problem ist, aber es ist einfach komisch.)Manuelle Speicherverwaltung ist etwas, mit dem Anfänger von Objective-C am meisten Probleme zu haben scheinen, vor allem, weil sie denken, dass es komplexer ist als es ist.
Ziel C und Kakao stützen sich auf Konventionen über die Durchsetzung; Wenn Sie ein sehr kleines Regelwerk kennen und befolgen, erhalten Sie durch die dynamische Laufzeit im Gegenzug viel kostenlos.
Die nicht 100% wahre Regel, aber gut genug für den Alltag ist:
alloc
sollte mit einemrelease
am Ende des aktuellen Bereichs abgeglichen werden .alloc
, sollte er zurückgegeben werden,return [value autorelease];
anstatt mit a übereinzustimmenrelease
.Die längere Erklärung folgt.
Die Speicherverwaltung basiert auf dem Besitz. Nur der Eigentümer einer Objektinstanz sollte das Objekt jemals freigeben, alle anderen sollten immer nichts tun. Dies bedeutet, dass Sie in 95% des gesamten Codes Objective-C so behandeln, als wäre es Müll gesammelt.
Was ist also mit den anderen 5%? Sie müssen auf drei Methoden achten. Jede von dieser Methode empfangene Objektinstanz gehört dem aktuellen Methodenbereich :
alloc
new
odernewService
.copy
undmutableCopy
.Die Methode hat drei mögliche Optionen, was mit ihren eigenen Objektinstanzen zu tun ist, bevor sie beendet wird:
release
wenn es nicht mehr benötigt wird.autorelease
.Wann sollten Sie also proaktiv die Verantwortung übernehmen, indem Sie anrufen
retain
? Zwei Fälle:quelle
Sicher, wenn alles, was Sie in Ihrem Leben gesehen haben, Ziel C ist, dann scheint seine Syntax die einzig mögliche zu sein. Wir könnten Sie eine "Programmierjungfrau" nennen.
Da jedoch viel Code in C, C ++, Java, JavaScript, Pascal und anderen Sprachen geschrieben ist, werden Sie feststellen, dass sich ObjectiveC von allen unterscheidet, jedoch nicht in guter Weise. Hatten sie einen Grund dafür? Sehen wir uns andere beliebte Sprachen an:
C ++ hat C viele Extras hinzugefügt, aber die ursprüngliche Syntax wurde nur so weit wie nötig geändert.
C # hat im Vergleich zu C ++ viele Extras hinzugefügt, aber nur Dinge geändert, die in C ++ hässlich waren (wie das Entfernen des "::" von der Benutzeroberfläche).
Java hat viele Dinge geändert, aber die bekannte Syntax beibehalten, außer in Teilen, in denen die Änderung erforderlich war.
JavaScript ist eine vollständig dynamische Sprache, die viele Dinge kann, die ObjectiveC nicht kann. Dennoch haben die Entwickler keine neue Methode zum Aufrufen von Methoden und Übergeben von Parametern erfunden, um sich vom Rest der Welt zu unterscheiden.
Visual Basic kann Parameter wie ObjectiveC nicht in der richtigen Reihenfolge übergeben. Sie können die Parameter benennen, aber Sie können sie auch auf normale Weise übergeben. Was auch immer Sie verwenden, es ist eine normale, durch Kommas getrennte Art und Weise, die jeder versteht. Komma ist das übliche Trennzeichen, nicht nur in Programmiersprachen, sondern in Büchern, Zeitungen und der Schriftsprache im Allgemeinen.
Object Pascal hat eine andere Syntax als C, aber seine Syntax ist für den Programmierer einfacher zu lesen (vielleicht nicht für den Computer, aber wen interessiert es, was der Computer denkt). Vielleicht schweiften sie ab, aber zumindest ist ihr Ergebnis besser.
Python hat eine andere Syntax, die (für Menschen) noch einfacher zu lesen ist als Pascal. Als sie es geändert und anders gemacht haben, haben sie es zumindest für uns Programmierer besser gemacht.
Und dann haben wir ObjectiveC. Hinzufügen einiger Verbesserungen zu C, aber Erfinden einer eigenen Schnittstellensyntax, Methodenaufruf, Parameterübergabe und was nicht. Ich frage mich, warum sie nicht + und - getauscht haben, so dass plus zwei Zahlen subtrahiert. Es wäre noch cooler gewesen.
Steve Jobs hat es vermasselt, ObjectiveC zu unterstützen. Natürlich kann er C # nicht unterstützen, was besser ist, gehört aber zu seinem schlechtesten Konkurrenten. Dies ist also eine politische Entscheidung, keine praktische. Technologie leidet immer, wenn technische Entscheidungen aus politischen Gründen getroffen werden. Er sollte das Unternehmen führen, was er gut macht, und Programmierangelegenheiten echten Experten überlassen.
Ich bin mir sicher, dass es noch mehr Apps für das iPhone geben würde, wenn er iOS schreiben und Bibliotheken in einer anderen Sprache als ObjectiveC unterstützen würde. Für alle außer eingefleischten Fans, jungfräulichen Programmierern und Steve Jobs sieht ObjectiveC lächerlich, hässlich und abstoßend aus.
quelle
NSArray
und es übernimmt die Auswahl des besten Algorithmus basierend auf der Maschine und der Art der Daten.Eine Sache, die ich an Objective-C liebe, ist, dass das Objektsystem auf Nachrichten basiert. Damit können Sie wirklich nette Dinge tun, die Sie in C # nicht tun konnten (zumindest nicht, bis sie das dynamische Schlüsselwort unterstützen!).
Eine weitere großartige Sache beim Schreiben von Kakao-Apps ist der Interface Builder, der viel besser ist als der Formular-Designer in Visual Studio.
Die Dinge an obj-c, die mich (als C # -Entwickler) nerven, sind die Tatsache, dass Sie Ihren eigenen Speicher verwalten müssen (es gibt eine Speicherbereinigung, aber das funktioniert auf dem iPhone nicht) und dass es aufgrund dessen sehr ausführlich sein kann die Selektorsyntax und alle [].
quelle
dynamic
Sie werden nur auf halbem Weg sein - die Implementierung eines echten dynamischen Objekts, selbst bei trivialen Dingen wie der Delegierung von Nachrichten, ist selbst in C # 4.0 mühsam. Auf der anderen Seite geht der Preis für Flexibilität echte dynamische Nachricht, die a la ObjC übergibt, an Sicherheit verloren.System.Reflection
Kombination mit Erweiterungen in C # 3.0 tun. Sie können jede Methode aufrufen, die Sie finden. Dies ist jedoch keine echte Nachrichtenübergabe. Es siehtobj.PassMessage("function_name", params object[] args);
nach einer besseren Nachrichtenübermittlung aus, die in die Sprache integriert ist. Eine fehlende Methode, die auf einem normalen Objekt aufgerufen werden kann, wäre erforderlich.Als Programmierer, der gerade mit Objective-C für iPhone aus C # 4.0 anfängt, fehlen mir Lambda-Ausdrücke und insbesondere Linq-to-XML. Die Lambda-Ausdrücke sind C # -spezifisch, während Linq-to-XML eher ein Kontrast zwischen .NET und Kakao darstellt. In einer Beispiel-App, die ich schrieb, hatte ich XML in einer Zeichenfolge. Ich wollte die Elemente dieses XML in eine Sammlung von Objekten analysieren.
Um dies in Objective-C / Cocoa zu erreichen, musste ich die NSXmlParser-Klasse verwenden . Diese Klasse basiert auf einem anderen Objekt, das das NSXMLParserDelegate- Protokoll mit Methoden implementiert , die aufgerufen werden (read: messages sent), wenn ein offenes Element-Tag gelesen wird, wenn einige Daten gelesen werden (normalerweise innerhalb des Elements) und wenn ein Element-End-Tag gelesen wird . Sie müssen den Analysestatus und -status verfolgen. Und ich habe ehrlich gesagt keine Ahnung, was passiert, wenn das XML ungültig ist. Es ist großartig, um auf die Details zu kommen und die Leistung zu optimieren, aber oh man, das ist eine Menge Code.
Im Gegensatz dazu ist hier der Code in C #:
Und das war's, Sie haben eine Sammlung von benutzerdefinierten Objekten, die aus XML gezeichnet wurden. Wenn Sie diese Elemente nach Wert filtern möchten oder nur nach solchen, die ein bestimmtes Attribut enthalten, oder wenn Sie nur die ersten 5 möchten oder die erste 1 überspringen und die nächsten 3 erhalten möchten oder einfach herausfinden möchten, ob Elemente zurückgegeben wurden ... BAM, alles in der gleichen Codezeile.
Es gibt viele Open-Source-Klassen, die diese Verarbeitung in Objective-C erheblich vereinfachen, sodass ein Großteil des schweren Hebens erledigt wird. Es ist einfach nicht so eingebaut.
* HINWEIS: Ich habe den obigen Code nicht kompiliert, er dient nur als Beispiel, um den relativen Mangel an Ausführlichkeit zu veranschaulichen, der für C # erforderlich ist.
quelle
Der wahrscheinlich wichtigste Unterschied ist die Speicherverwaltung. Mit C # erhalten Sie eine Speicherbereinigung, da es sich um eine CLR-basierte Sprache handelt. Mit Objective-C müssen Sie den Speicher selbst verwalten.
Wenn Sie aus einem C # -Hintergrund (oder einer anderen modernen Sprache) stammen, ist der Wechsel zu einer Sprache ohne automatische Speicherverwaltung sehr schmerzhaft, da Sie einen Großteil Ihrer Codierungszeit für die ordnungsgemäße Verwaltung des Speichers (und das Debuggen als) aufwenden Gut).
quelle
Hier ist ein ziemlich guter Artikel zum Vergleich der beiden Sprachen: http://www.coderetard.com/2008/03/16/c-vs-objective-c/
quelle
Abgesehen vom Paradigmenunterschied zwischen den beiden Sprachen gibt es keinen großen Unterschied. So sehr ich es auch hasse, Sie können mit .NET und C # die gleichen Dinge tun (wahrscheinlich nicht so einfach) wie mit Objective-C und Cocoa. Ab Leopard verfügt Objective-C 2.0 über eine Speicherbereinigung , sodass Sie den Speicher nur dann selbst verwalten müssen , wenn Sie dies möchten (Codekompatibilität mit älteren Macs und iPhone-Apps sind zwei Gründe).
In Bezug auf strukturierten, lesbaren Code liegt der größte Teil der Belastung beim Programmierer, wie bei jeder anderen Sprache. Ich finde jedoch, dass sich das Paradigma der Nachrichtenübergabe gut für lesbaren Code eignet, vorausgesetzt, Sie benennen Ihre Funktionen / Methoden entsprechend (wie jede andere Sprache auch).
Ich gebe als Erster zu, dass ich mit C # oder .NET nicht sehr vertraut bin. Aber die Gründe, die Quinn oben aufgeführt hat, sind einige Gründe, warum ich es nicht möchte.
quelle
Die in obj-c verwendeten Methodenaufrufe ermöglichen einen leicht lesbaren Code, meiner Meinung nach viel eleganter als c #, und obj-c basiert auf c, sodass der gesamte c-Code in obj-c einwandfrei funktionieren sollte. Der große Verkaufsschlager für mich ist jedoch, dass obj-c ein offener Standard ist, sodass Sie Compiler für jedes System finden können.
quelle