von Ryan Green
Die meiste Zeit meiner Laufbahn habe ich im Web verbracht. Nun, meinen ersten richtigen Job hatte ich als Hilfskraft in einem winzigen mexikanischen Restaurant (ich liebe Salsa!). Anschließend war ich stolzer Mitarbeiter einer Fast-Food-Burger-Kette, deren Logo goldene Bögen zieren (klicken Sie hier, um zu den Hauptzutaten dieses Beitrags zu gelangen). Und schließlich startete ich als junger Webdesigner eine vielversprechende Karriere. Es ist erstaunlich, welche Jobs man zur Zeit der Dotcom-Blase mit ein wenig Photoshop-Knowhow und Microsoft Frontpage an Land ziehen konnte.
Etwas, das ich während meiner Zeit als Webmaster schnell lernte – neben der Kunst, geschachtelte HTML-Tabellenlayouts mit perfekter Pixelgestaltung zu kreieren, damit sich meine Webseiten in den 1990ern mit einem 28,8-K-Modem laden ließen, war Folgendes: Wenn man Kunden neben der Gestaltung ihrer vierseitigen Farbbroschüre in Webformat etwas Wertvolles liefern wollte, dann musste man sich mit Datenbanken und einer Art von serverseitigem Skripting auskennen.
Ich entschied mich für Cold Fusion. Ausschlaggebend für diese Entscheidung war damals, dass dieses Buch das einzige in unserem kleinen Büro war, in dessen Titel weder „CGI“ noch „Perl“ vorgekommen ist. Cold Fusion bot eine ansprechende Tag-basierte Syntax, mit der sich eine Verbindung zu einer Datenbank herstellen und Traktorbestandteile auf einer Webseite anzeigen ließen. Dann kamen JavaScript und DHTML und VBScript und PHP und, zu guter Letzt, ActionScript 1 und 2.
Nun, bevor Sie fürchten, dass ich eines schnellen Todes sterben könnte, da ich bis oben mit obskurem Skripting-Knowhow vollgestopft bin: ActionScript 3 mit Flex wurde gerade rechtzeitig eingeführt, um nicht den Zorn von Java-Tüftlern auf mich zu ziehen, die den Tod von Cold Fusion und anderen „Unsprachen“ begeistert umjubelten. Die Sprache der Benutzeroberfläche ist zunehmend den Kinderschuhen entwachsen, hat sich zu einer Art objektorientierter Syntax gewandelt und setzt XML für die Definition der Benutzeroberfläche intelligenter ein. „Echte Programmierer“ haben sich mit Objective-C/C++/C#/C-Dur und C#-Moll angefreundet. Und dann gibt es natürlich noch Java auf dieser kleinen mobilen Plattform namens Android ... und wie könnte ich Ruby und Python vergessen.
Nun, eigentlich wollte ich nur zum Ausdruck bringen, dass wir es im Hier und Heute mit einer fragmentierten Mischung von Sprachen und Plattformen zu tun haben, die alle um den Titel der „großartigsten echten Programmiersprache“ kämpfen.
Meine Nominierung für einen neuen Eintrag im Lexikon der echten Programmiersprachen ist ActionScript/MXML, eine Syntax, die JavaScript die Objektorientierung und dem HTML-Tag echte Namespaces und benutzerdefinierte Tag-Namen verleiht.
Syntaxunterschiede zwischen Objective-C/C/C++ und ActionScript 3
ActionScript ist ein Produkt der ECMA-Skriptspezifikation, die wiederum zur Familie der C-Programmiersprachen gehört. In Bezug auf die grundlegende Syntax (Operatoren, Bedingungsanweisungen und Enumerationen) sind Objective-C und ActionScript beinahe identisch.
Objective-C/C/C++ | ActionScript 3 | |
Kalkulation | +, -, /, *, ++ (Inkrement), -- (Dekrement), % (Modulo) | Identisch |
Zuweisung | = | Identisch |
Vergleich | ==, !=, ===, !==, >, <, >=, <= | Identisch |
Kommentar | /* */, // | Identisch plus <!-- --> für MXML |
Logik | &&, ||, ! | Identisch |
Null |
| null |
If-Anweisung | if(condition) { | Identisch |
Switch/Case |
| Identisch |
Schnelle Enumeration | for(Type newVariable in collection) { | for(var value:Type in collection) { |
Do/While | while(expression) { | Identisch |
For | for(int value = start; value <= end; value++) { | for(var value:int = start; value <= end; value++) { |
Ternär | return (i > 0) ? true : false; | Identisch |
Allerdings gibt es Unterschiede in den Sprachen bei der Instanziierung und Deklaration von Variablen und Methoden sowie der Meldung von Objekten.
Primitive Datentypen
Objective-C/C/C++ | ActionScript 3 | |
Datentypdokumentation | ||
Boolesche Datentypen | BOOL mine = YES; BOOL mine = NO; | var mine:Boolean = true; |
Integer | int i = 1; | var i:int = 1;
|
Fließkommawerte | float pi = 3.14; | var pi:Number = 3.14;
|
Zeichenkette | NSString *fname = @"Ryan"; | var fname:String = "Ryan"; |
Deklaration von Klassen
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation | Dokumentation zur Deklaration von Klassen | Dokumentation zur Deklaration von Klassen |
Klasse deklarieren | //-- File ClassName.h //import dependencies #import "dependent.h"; @interface ClassName : SuperClass { @public|@private|@protected|@package //declare instance variables Type variableName; } //declare properties @property (nonatomic, retain) variableName; //constructor -(id)init; //declare instance methods -(Type *)forThisObject: (Type *)obj makeSize: (int)size; //declare static methods +(void)doSomething: (Type *)thisObject; @end //-- File ClassName.m @implementation ClassName //generate getter/setters @synthesize; //implement instance methods -(id)forThisObject: (id *)thisObject makeSize: (int)size { } //implement static methods +(id)doSomething: (id *)thisObject { } @end |
|
Deklaration von Variablen
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation zur Deklaration von Variablen | ||
Instanzenvariablen (mit Zugriff von außerhalb der Klasse) |
|
|
Statische Klassenvariablen |
| //-- Datei ClassName.as |
Lokale Variablen |
|
|
Zugriff auf Eigenschaften | obj.propertyName; | obj.propertyName; |
Implementierung von Methoden/Funktionen
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation zur Deklaration von Funktionen | ||
| public function methodName(arg1:Type, arg2:Type):Type { } |
Getter/Setter-Implementierung
Objective-C/C/C++ | ActionScript 3 | |
Getter/Setter-Dokumentation | ||
| /* Getter/Setter-Funktionen haben möglicherweise nicht denselben
|
Instanziierung von Klassen
Objective-C/C/C++ | ActionScript 3 | |
Type *class = [[Type alloc] init]; | var class:Type = new Type(); |
Behandlung grundlegender Datentypen
ActionScript-Objekte sind im Allgemeinen immer veränderbar und so wie Objective-C nutzt auch ActionScript die Reflektion.
Reflektion
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation | Dokumentation zur Reflektion (mit Referenz zu Beispielen) | |
Deklaration von Klassen | Class cls = NSClassFromString(@"Foo"); | var class:Class = getDefinitionByName("Foo") as Class; |
Aufruf dynamischer Methoden |
|
|
Behandlung von Strings
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation | Dokumentation zur NSString-Klasse | Dokumentation zur String-Klasse |
Deklaration | NSString * str = @"The quick brown fox"; | var str:String = "The quick brown fox"; |
Verkettung | NSString * str2 = [str stringByAppendingString: @"jumped ..."]; | str = str + " jumped over the lazy river"; |
Ersetzen | NSString * final = [start stringByReplacingOccurancesOfString: @"find" withString: @"replace"]; | str = str.replace('find', 'replace'); |
Suchen | NSRange *range = [myString rangeOfString: @"string to find"]; | var idx:int = str.indexOf('string to find'); |
Substring | NSString *str2 = [str substringWithRange: NSMakeRange (0, 1)]; | var sub:String = ("string").substr(0, 1); |
Vergleich |
| var str:String = "first"; |
Behandlung von Arrays
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation | Dokumentation zur Array-Klasse | |
Deklaration |
|
|
Element am Ende hinzufügen | [a addObject: @"lemon"]; | a.push("lemon"); |
Element am Anfang einfügen | [a insertObjectAtIndex: @"lemon"]; | a.unshift("lemon"); |
Element am Ende entfernen | [a removeLastObject]; | var fruit:String = a.pop(); |
Element am Anfang entfernen | [a removeObjectAtIndex: 0]; | var fruit:String = a.shift(); |
Auf Element bei Index zugreifen | [a objectAtIndex: 0]; |
|
Element bei Index entfernen | [a removeObjectAtIndex: 1]; |
|
Array-Länge | [a count]; |
|
Behandlung von Dictionary-Objekten
Objective-C/C/C++ | ActionScript 3 | |
Dokumentation | Dokumentation zur Objektklasse | |
Deklaration | NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjects: [[NSArray alloc] initWithObjects: @"Ryan", @"Green"] forKeys: [[NSArray alloc] initWithObjects: @"firstname", @"lastname"] | var object:Object = {firstname:"Ryan", lastname:"Green"}; |
Objekt für Schlüssel setzen | [dict setObject: @"D" forKey: @"middleinitial"]; | object.middleinitial = "D"; |
Objekt für Schlüssel entfernen | [dict removeObject: @"D" forKey: @"middleinitial"]; | delete object.middleinitial; |
Objekt nach Schlüssel beziehen | [dict objectForKey: @"middleinitial"]; | if(object.hasOwnProperty('middleinitial')) { |
Terminator/Cleanup
Okay, Sie haben mich erwischt. ActionScript ist eine der Sprachen, die keine direkte Garbagecollection zulässt. Wenn Sie allerdings alle Referenzen auf Ihre Objekte erfolgreich freigeben, verspricht Flash, die Überreste einzusammeln ... irgendwann einmal.
Objective-C/C/C++ | ActionScript 3 | |
Speicher freigeben | [object release]; |
|
Nun wird alles zusammengesetzt
Objective-C/C/C++ | ActionScript 3 | |
Schnittstelle für „Favorite Foods“ |
| |
„Favorite Foods“-Klasse | //-- Datei FavoriteFoods.m
} | //-- Datei FavoriteFoods.m }
|
Verwalten der „Favorite Foods“-Klasse | //-- Datei ManageFavoriteFoods | //-- Datei ManageFavoriteFoods |
Okay, das war also unser kurzer Überblick zur ActionScript-Syntax. Wahrscheinlich werden Sie die Erfahrung machen, dass AS3 große Ähnlichkeiten mit JavaScript aufweist und weniger weitschweifig ist als Objective-C. Wenn Sie es jedoch mit dem Flex-SDK kombinieren, werden Sie in Flex die logische Folge der meisten Objective-C-Funktionen finden.
Bei einem früheren Portierungsprojekt von der iPhone-Plattform und Objective-C nach Flex und AS3 habe ich festgestellt, dass sich die Logik und Syntax des nicht für die Benutzeroberfläche bestimmten Codes (d. h. Klassenstruktur-, logische und graphische APIs) in vielen Fällen beinahe direkt portieren lassen. Ich kopierte C-Code und korrigierte einfach die Syntax. Hier liegt im Vergleich zur herkömmlichen Flash-Entwicklung die Stärke einer Codebasis wie Flex. Bei Flex gibt es keine zeitliche Einschränkung oder Phase, in der man Codefragmente in Frames und unter Schaltflächen speichert. Daher kann Flex „echten Programmierern“ durch objektorientierte Syntax und eine klassenbasierte Codestruktur einen wesentlich bequemeren Umstieg zur Flash-Programmierung bieten.
Schauen Sie bald wieder vorbei! In meinem nächsten Artikel sehen wir uns die SDKs, Vergleichs-/Kontrast-UI-Muster und Implementierungsunterschiede genauer an, damit Sie beim Portieren der Benutzeroberfläche von Cocoa nach Flex einem vorgegebenen Pfad folgen können.
Wenn Sie Teil 1 dieser Reihe verpasst haben, empfehle ich Ihnen, den Artikel zu lesen. Im ersten Teil stelle ich Flash vor und präsentiere einen kurzen Vergleich zwischen dem Cocoa- und dem Flex-SDK.