Quantcast
Channel: Recent posts
Viewing all articles
Browse latest Browse all 13

Portieren vom iPhone zum Netbook mit Flex – Erläuterungen zur Syntax von ActionScript und MXML

$
0
0

von Ryan Green

Flex-BurgerDie 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

nil (für den Vergleich mit Objective-C-Objekten)
Nil (für den Vergleich mit Objective-C-Klassen)
NULL (für den Vergleich mit allem anderen)

null
If-Anweisungif(condition) {
  //wenn condition wahr ergibt
}
else if(condition2) {
 //wenn condition2 wahr ergibt
}
else {
  //wenn condition und condition2 falsch ergeben
}
Identisch
Switch/Case

switch(expression) {
  case value1:
   //Anweisungen
   break;
  case value2:
   //Anweisungen
   break;
  default:
   //Anweisungen
   break;
}

Identisch
Schnelle Enumerationfor(Type newVariable in collection) {
  //Anweisungen
}
for(var value:Type in collection) {
  //Anweisungen
}
Do/Whilewhile(expression) {
  //Anweisungen
}
Identisch
Forfor(int value = start; value <= end; value++) {
  //Anweisungen
}
for(var value:int = start; value <= end; value++) {
  //Anweisungen
}
Ternärreturn (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 DatentypenBOOL mine = YES;
BOOL mine = NO;
var mine:Boolean = true;
var mine:Boolean = false;
Integerint i = 1;var i:int = 1;
Fließkommawertefloat pi = 3.14;var pi:Number = 3.14;
ZeichenketteNSString *fname = @"Ryan";var fname:String = "Ryan";

Deklaration von Klassen

 Objective-C/C/C++

ActionScript 3

DokumentationDokumentation zur Deklaration von KlassenDokumentation 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

//-- Datei ClassName.as
package {

//Abhängigkeiten importieren
  import dependant;
  public class ClassName extends SuperClass {
    //Instanzenvariablen deklarieren
   public|private|protected var variableName:Type;
   //Konstruktor
   public function ClassName():void {
    }
   //Instanzenmethoden deklarieren
   public function makeSize(obj:Type, size:int):Type {

      //Implementierung
   }
   //statische Methoden deklarieren
   public static function doSomething(
obj:Type):void {
     //Implementierung
    }
  }
}

Deklaration von Variablen

 Objective-C/C/C++

ActionScript 3

  Dokumentation zur Deklaration von Variablen
Instanzenvariablen (mit Zugriff von außerhalb der Klasse)

//-- Datei ClassName.h
@interface ClassName {
  Type *variableName;
}
@property (nonatomic, retain) variableName;
@end

//-- Datei ClassName.m
@implementation ClassName
  @synthesize variableName;
@end

//-- Datei ClassName.as
package {
  public class ClassName {
    private var _variableName:Type;
   public function get variableName():Type {
     return _variableName;
   }
   public function set variableName(value:Type):void {
     _variableName = value;
   }
  }
}


oder

//-- Datei ClassName.as
package {
  public class ClassName {
    public var variableName:Type;
  }
}

Statische Klassenvariablen

//-- Datei ClassName.h
@interface ClassName {
  Type *variableName;
}
@end

//-- Datei ClassName.m
@implementation ClassName
  static Type *variableName;
  +(Type *)variableName {
    return variableName; }
  +(void)variableName: (Type *)newVar {
    variableName = newVar;
  }

@end

//-- Datei ClassName.as
package {
  public class ClassName {
    public static var variableName:Type;
  }
}
Lokale Variablen

(int) i;

oder

(NSString *) fname;

var i:int;

oder

var fname:String;

Zugriff auf Eigenschaftenobj.propertyName;
obj->propertyName;
obj.propertyName;

 

Implementierung von Methoden/Funktionen

 Objective-C/C/C++

ActionScript 3

  Dokumentation zur Deklaration von Funktionen
 

@interface {}
-(Type *) methodName: (Type *)arg1 byArg2: (Type *)arg2;
@end

@implementation ClassName
-(Type *) methodName: (Type *)arg1 byArg2: (Type *)arg2 {

}
@end

public function methodName(arg1:Type, arg2:Type):Type { }

Getter/Setter-Implementierung

 Objective-C/C/C++

ActionScript 3

  Getter/Setter-Dokumentation
 

@synthesize propertyName;

oder

-(Type *) propertyName { return propertyName; }
-(void) propertyName: (Type *)newVal { propertyName = newVal; }

/* Getter/Setter-Funktionen haben möglicherweise nicht denselben
Namen wie private Instanzenvariablen */

private var _propertyName;
public function get propertyName():Type {
   return _propertyName;
}

public function set propertyName(value:Type):void {
  _propertyName = value;
}

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 KlassenClass cls = NSClassFromString(@"Foo");
id foo = [[cls alloc] init];
var class:Class = getDefinitionByName("Foo") as Class;
var foo:Class = new class();
Aufruf dynamischer Methoden

SEL selector = NSSelectorFromString(@"hello");
[foo performSelector:selector withObject:nil];

foo["hello"]();

Behandlung von Strings

 Objective-C/C/C++

ActionScript 3

DokumentationDokumentation zur NSString-KlasseDokumentation zur String-Klasse
DeklarationNSString * str = @"The quick brown fox"; var str:String = "The quick brown fox";
VerkettungNSString * str2 = [str stringByAppendingString: @"jumped ..."]; str = str + " jumped over the lazy river";
ErsetzenNSString * final = [start stringByReplacingOccurancesOfString: @"find" withString: @"replace"]; str = str.replace('find', 'replace');
SuchenNSRange *range = [myString rangeOfString: @"string to find"];
//gibt {NSNotFound, 0} zurück, wenn String nicht gefunden wurde
var idx:int = str.indexOf('string to find');
//gibt -1 zurück, wenn String nicht gefunden wurde;
SubstringNSString *str2 = [str substringWithRange: NSMakeRange (0, 1)]; var sub:String = ("string").substr(0, 1);
trace(sub); //<-- Ausgabe "s"
Vergleich

NSComparisonResult result = [str compare: @"first"];
// Ergebnis == YES

var str:String = "first";
var b:Boolean = (str == "first");
trace(b); //<-- Ausgabe: "true"

Behandlung von Arrays

 Objective-C/C/C++ActionScript 3
Dokumentation

Dokumentation zur NSMutableArray-Klasse

Dokumentation zur Array-Klasse
Dokumentation zur ArrayCollection-Klasse

Deklaration

NSArray *a = [[NSArray alloc] initWithObjects: @"apple", @"orange", @"grape"];
NSMutableArray *b = [[NSMutableArray alloc] init];
[b addObjectsFromArray: a];

oder
NSMutableArray *a = [[NSMutableArray] alloc] init];

var a:Array = ["apple","orange","grape"];
oder
var a:Array = new Array();

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];

var a:Array = ["apple", "pear"];
trace(a[0]); //<-- Ausgabe: "apple"
trace(a[1]); //<-- Ausgabe: "pear"

Element bei Index entfernen[a removeObjectAtIndex: 1];

var a:Array = ["apple", "pear", "peach"];
a.splice(1, 1);

Array-Länge[a count];

var a:Array = [0, 1, 2, 3, 4];
trace(a.length); //<-- Ausgabe: "5"

Behandlung von Dictionary-Objekten

 Objective-C/C/C++

ActionScript 3

Dokumentation

Dokumentation zur NSMutableDictionary-Klasse

Dokumentation zur Objektklasse
Dokumentation zur Dictionary-Klasse

DeklarationNSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjects: [[NSArray alloc] initWithObjects: @"Ryan", @"Green"] forKeys: [[NSArray alloc] initWithObjects: @"firstname", @"lastname"]
oder
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
var object:Object = {firstname:"Ryan", lastname:"Green"};
oder
var object:Object = new Object();
Objekt für Schlüssel setzen[dict setObject: @"D" forKey: @"middleinitial"]; object.middleinitial = "D";
oder
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')) {
 return object.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];

delete object;

Nun wird alles zusammengesetzt

 Objective-C/C/C++

ActionScript 3

Schnittstelle für „Favorite Foods“

//-- Datei FavoriteFoods.h
@interface FavoriteFoods : NSObject {
  NSMutableArray *foods;
}

@property (nonatomic, retain) *foods;
-(void)init;
-(void)addFavoriteFood:(NSString *)food;
+(BOOL)badForMe:(NSString *)food howMany: (int)count;
@end



„Favorite Foods“-Klasse//-- Datei FavoriteFoods.m
@implementation FavoriteFoods
  @synthesize foods;
  -(id)init {
   foods = [[NSMutableArray alloc] init];
   return self;
  }
  -(void)addFavoriteFood:(NSString *)food {
   [foods addObject: food];
  }
  +(BOOL)badForMe:(NSString *)food howMany: (int)count {
   if([food compare: @"1 pound hamburger"] == YES) {
     switch(count) {
      case 0:
      case 1:
        return NO;
      break;
      default:
        return YES;

     }
    }
   else {
     return NO;
    }
  }
  -(void)dealloc {
   [foods release];
  }
@end
//-- Datei FavoriteFoods.m
package {
  public class FavoriteFoods {
   public var foods:Array;
   public function FavoriteFoods():void {
     foods = new Array();
    }
 public function addFavoriteFood(food:String):void {
   foods.push(food);
   }
 public static function badForMe(food:String,  count:int):Boolean {
   if(food == "1 pound hamburger) {
    switch(count) {
      case 0:
      case 1:
       return false;
      break;
      default:
       return true;

       }
     }
     else {
      return false;
     }
    }
  }
}
Verwalten der „Favorite Foods“-Klasse//-- Datei ManageFavoriteFoods
...
#import "FavoriteFoods.h";
...
FavoriteFoods *favorites = [[FavoriteFoods alloc] init];
NSString *food = @"1 pound hamburger";
[favorites addFavoriteFood: food];
printf([FavoriteFoods badForMe: food howMany: 5]); //Ausgabe: YES
[favorites release];
//-- Datei ManageFavoriteFoods
...
import FavoriteFoods;
...
var favorites:FavoriteFoods = new FavoriteFoods();
var food:String = "1 pound hamburger";
favorites.addFavoriteFood(food);
trace(FavoriteFoods.badForMe(food, 5)); //verfolgt true;
delete favorites;

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.


Viewing all articles
Browse latest Browse all 13


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>