User:Staeff/Objective-C

Objective-C ist eine objektorientierte Erweiterung der Programmiersprache C, deren Syntax an Smalltalk angelehnt ist.

Geschichte
Objective-C wurde in den frühen 80er Jahren von Brad Cox für die Firma PPI, später Stepstone geschaffen.

NeXTStep und Apple
Da die Geschichte von Objective-C sehr stark mit der Geschichte der NeXTStep- und Apple-Betriebssysteme verknüpft ist, werden im folgenden die wichtigsten Punkte in der Entwicklung dieser Systeme aufgeführt.

Im Jahre 1985 verließ Steve Jobs die von ihm gegründete Firma Apple, um die Firma NeXT zu gründen. Das Ziel der Gründung von NeXT war die Entwicklung von NeXTStep, einem UNIX-basierten Betriebssystem mit grafischer Benutzeroberfläche, dessen API in Objective-C geschrieben war. Mit der durchgängigen Verwendung objektorientierter Konzepte und dem Vorhandensein eines fortschrittlichen Interface-Builders war NeXTStep vielen anderen Systemen dieser Zeit weit voraus.

1994 wird von NeXT und Sun der OpenStep-Standard verabschiedet, welcher eine betriebssystemunabhängige Schnittstelle zur Objective-C Programmierung definiert, welche auf der NeXTStep-API basiert.

Im Frühjahr 1997 wird NeXT von Apple aufgekauft, da das neue Apple-Betriebssystem Mac OS X auf NeXTStep basieren soll. Die meisten Objective-C Programme werden heute für die Apple-Plattform (Mac OS X und iOS) geschrieben.

Ziele bei der Entwicklung
Die Ziele der Entwicklung von Objective-C durch Brad Cox waren:


 * „Evolution statt Revolution“
 * Nahtlose Einbindung in bestehende Softwaresysteme
 * Wiederverwendbarkeit

Das Motto „Evolution statt Revolution“ umschreibt hierbei das Prinzip, auf bewährte Technologien aufzusetzen, anstatt das Rad neu zu erfinden.

Speziell Entwickelte sich daraus die Idee Objective-C auf einer bereits existierenden und bewährten Sprache aufbauen zu lassen – nämlich der Sprache C. Außerdem wurde der Objektorientierte Ansatz und große Teile der Syntax von Smalltalk, die damals als die objektorientierte Sprache schlechthin galt, übernommen.

Da Objective-C direkt von C abgeleitet ist, kann man Objective-C-Programme direkt mit vorhandenem C-Code mischen und somit bereits vorhandene Bibliotheken und Programmteile weiterhin verwenden. Auch ist der Lernaufwand für einen C-Programmierer sehr gering und die vorhandenen Compiler sehr ausgereift.

Syntax
Die Syntax von Objective-C erweitert die C-Syntax um objektorientierte Elemente. Diese Syntaxerweiterungen lehnen sich jedoch nicht an die C-Syntax an, wie es etwa viele verbreitete objektorientierte Programmiersprachen tun, sondern an die der Programmiersprache Smalltalk. Der Hintergrund ist, dass der objektorientierte Aufsatz sich grundsätzlich auch mit anderen Programmiersprachen kombinieren lässt, etwa mit Pascal zu Objective-Pascal. Sämtliche neuen Schlüsselwörter sind mit einem voranstehenden @ gekennzeichnet.

Klassendefinition
Jede Klasse benötigt als Definition, dass im @interface -Teil – gewöhnlich in einer Header-Datei (mit der Endung .h) – die Klasse, deren Instanzvariablen und Methoden definiert werden. Wenn die Klassendefinition nicht in einer Headerdatei sondern gemeinsam mit der Implementierung erfolgt ist diese Klasse nach außen nicht sichtbar.

Dabei ist zu beachten, dass Interface hierbei nicht die selbe Bedeutung wie in Java besitzt, sondern nur als Bekanntmachung der Schnittstellen einer Klasse für andere Klassen dient. Hier im Beispiel eine Bruch-Klasse.

Im Einzelnen:

Klassenbezeichnung und Vererbung
Jede Klasse hat einen Namen, der konventionsgemäß mit einem Großbuchstaben beginnt und im Camel-Case (neueWoerterErhaltenWiederEinenGroßbuchstaben) fortgeführt wird. Die Bezeichner folgen den C-Regeln, dürfen also insbesondere keine Umlaute enthalten. Durch einen Doppelpunkt getrennt wird dann die Basisklasse angegeben. Schließlich können in spitzen Klammern Protokolle (werden in einem späteren Abschnitt genauer erklärt) angegeben werden, deren Implementierung versprochen wird. Handelt es sich um mehrere Protokolle, so sind deren Namen in den Klammern mit Kommata getrennt aufzulisten.

Instanzvariablen
Es folgt in geschweiften Klammern die Liste der Instanzvariablen.

Diese werden für jede Instanz angelegt. Die Sichtbarkeit lässt sich über Abschnitte mit


 * @public
 * @private
 * @protected
 * @package (nur bei 64-Bit-Laufzeitsystem)

steuern. @public bedeutet hierbei, dass jeder auf diese Instanzvariable zugreifen darf, @protected, dass dies nur im Code derselben Klasse oder abgeleiteten Klassen erfolgen darf, @private dass dies nur in derselben Klasse erfolgen darf und @package , dass dies nur in Klassen des Frameworks erfolgen darf. Standard ist @protected, welches wegen anderer Technologien (Properties) tatsächlich fast immer verwendet wird. Daher enthalten die allermeisten Klassendefinitionen keines der Schlüsselwörter zur Sichtbarkeit.

Properties
Nach den Instanzvariablen ist es seit Objective-C 2.0 möglich, Eigenschaften (Attribute oder Beziehungen) aufzulisten. Die Definition einer Property hat die Form

Die Attribute lassen sich hinsichtlich des Schreibschutzes, des Referenzmodelles und der Atomarität unterscheiden.


 * Für den Schreibschutz existieren die Attribute readonly und readwrite (Default)
 * Atomarität: Durch das Attribut nonatomic wird der Zugriff auf die Eigenschaft für Singlethread-Nutzung optimiert. Standardmäßig sind Eigenschaften sicher für die Verwendung in Multithread-Umgebungen, wofür kein gesondertes Attribut existiert.
 * Die Referenzierung wird über die Wörter assign (Default) als reine Zuweisung im Setter auch dann, wenn der Typ der Property ein Instanzzeiger ist, retain als Referenz im Sinne des Reference-Countings (der Parameter erhält die Nachricht retain) und copy, wenn der Setter eine Kopie anfertigen soll (der Parameter erhält die Nachricht copy), beschreiben.

Werden nur Default-Eigenschaften verwendet, so kann die Attributliste samt Klammer weggelassen werden:

Wird jedoch der Code mit Referenz-Counting als Speichermodell übersetzt und soll eine Eigenschaft mittels assign nur zugewiesen werden, so muss dies obwohl Default-Einstellung, explizit angegeben werden. Ansonsten erteilt der Compiler eine Warnung. Es bietet sich generell an, bei Instanzenzeigern explizit das Referenzmodell anzugeben, während es bei C-Typen überflüssig ist, da nur assign sinnvoll ist.

Methoden
Als nächstes folgt eine Liste von Methoden:

Jede einzelne Methodendeklaration beginnt zunächst mit einem + (Klassenmethode) oder - (Instanzmethode). Hiernach folgt in Klammern der Typ des Rückgabewertes, wobei wie in C void als Schlüsselwort für keinen Rückgabewert steht. Anschließend folgt der Methodenname, wobei wieder die Regeln für C-Bezeichner gelten. Soll die Methode einen Parameter enthalten, so folgt als Teil des Bezeichners die äußere Beschreibung des ersten Parameters, ein Doppelpunkt, in Klammern der Typ und sodann ein Bezeichner. Folgen noch Parameter, so werden diese nach einem Leerzeichen wieder mit einem beschreibenden Namen versehen (der auch 0 Zeichen haben kann), einem Doppelpunkt, in Klammern der Typ und sodann ein Bezeichner:

Abgeschlossen wird die Deklaration mit einem Semikolon.

Klassenmethoden
Objective-C besitzt so genannte Klassenobjekte. Dies bedeutet: Nicht nur die Instanzen, sondern auch die Klassen sind Objekte und können Nachrichten (siehe entsprechender Abschnitt) empfangen. Zum Instanzieren sind damit keine zusätzlichen Sprachelemente wie Konstruktoren und Schlüsselwörter nötig. +alloc ist kein Bestandteil der Sprachbeschreibung, sondern eine – beliebige – Methode des Frameworks und daher der eigenen Implementierung zugänglich. Die Methode zu überschreiben ist jedoch nur für Experten eine gute Idee. Ganz im Gegensatz dazu ist die Methode +initialize, die vor Verwendung einer Klasse aufgerufen wird, standardmäßig leer und kann für klassenbezogene Vorauseinstellungen überschrieben werden. Die Klassendefinition wird mit @end abgeschlossen.

Implementierung
Die Implementierung erfolgt üblicherweise in einer weiteren Datei, die standardmäßig auf .m endet (Eselsbrücke: iMplementation oder Module). Sie beginnt mit @implementation und endet mit einem @end. Dazwischen erfolgt die Implementierung der Methoden – gleichgültig, ob im Interface bekannt gemacht oder nicht. Dabei sind Standardmethoden und synthetisierte Methoden (nur Objective-C 2) für Eigenschaften (siehe oben) zu unterscheiden, Standardmethoden entsprechen in ihrem Kopf der Methodendeklaration. Jedoch tritt an die Stelle des Semikolons (das jedoch optional bleibt, unüblich!) die Anweisungsliste in geschweiften Klammern:

Die Bezeichner der formalen Parameter müssen nicht denen aus der Methodendeklaration entsprechen. Synthetisierte Methoden sind die Zugriffsmethoden für die Eigenschaften:

Es werden dann Zugriffsmethoden für die im Interface angegebenen Attribute erzeugt. Standardmäßig verwendet der Compiler dabei gleichnamige Instanzvariablen. Dem Programmierer bleibt es aber vorbehalten, selbst diese Methoden auszuformulieren, wobei diese den Namen eigenschaft und setEigenschaft (nur bei readwrite) tragen müssen:

Eine weitere Möglichkeit besteht darin, dass man eine Eigenschaft mittels @dynamic bezeichnet. In diesem Falle überprüft der Compiler nicht mehr das Vorhandensein in der Implementierung. Man kann also die entsprechenden Methoden zur Laufzeit simulieren oder selbst der Klasse hinzufügen: