Erste Schritte mit Objective-C
German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)
Einführung
Da die Grundlagen von C noch in Erinnerung sind, ist es an der Zeit, sich mit Objective-C vertraut zu machen. Der Hauptunterschied zu C besteht darin, dass Objective-C eine objektorientierte Programmiersprache ist, während C eine prozedurale Programmiersprache ist. Dies bedeutet, dass wir zuerst die Objekte und ihre Beziehung zu Klassen verstehen müssen. Andere Schlüsselkonzepte, die wir in diesem Artikel untersuchen werden, sind Objektnachrichten, Kapselung und Vererbung.
Die Ursprünge von Objective-C
Objective-C und Cocoa sind zwei Schlüsselkomponenten der iOS-Plattform. Trotz der Tatsache, dass die iOS-Plattform noch relativ jung ist, wurde Objective-C in den frühen 1980er Jahren bei StepStone von Brad Cox und Tom Love entwickelt. Die Sprache wurde entwickelt, um die robuste und agile C-Programmiersprache mit der eleganten Smalltalk-Sprache zu kombinieren. Objective-C ist eine strikte Obermenge von C und im Gegensatz zu C eine Programmiersprache auf hohem Niveau. Der Hauptunterschied zwischen C und Objective-C besteht darin, dass letztere eine objektorientierte Programmiersprache ist, während C eine prozedurale Programmiersprache ist.
Wie kam es, dass iOS eine Sprache verwendete, die in den 1980er Jahren entwickelt wurde? Kurz nach der Gründung von NeXT durch Steve Jobs wurde Objective-C von StepStone lizenziert. NeXT hat NeXTSTEP erstellt, ein Toolkit für die Benutzeroberfläche des in Objective-C entwickelten NeXT-Betriebssystems. Obwohl NeXTSTEP eine revolutionäre Reihe von Tools bereitstellte, gewann das NeXT-Betriebssystem auf dem Markt nur wenig an Bedeutung. 1996 erwarb Apple NeXT und aus NeXTSTEP wurde Cocoa. Letzteres wurde mit der Einführung von OS X im März 2001 und später mit der Veröffentlichung des iPhone und des iOS-Betriebssystems zum Mainstream.
Objekt orientierte Programmierung
Bei der prozeduralen Programmierung besteht ein Programm aus einer Reihe von Prozeduren oder Routinen, die ausgeführt werden, um einen bestimmten Zustand zu erreichen. Bei der objektorientierten Programmierung interagieren jedoch eine Sammlung von Objekten und arbeiten zusammen, um eine Aufgabe zu erledigen. Obwohl das Endergebnis identisch sein kann, unterscheiden sich die Methodik und die zugrunde liegenden Paradigmen erheblich. Modularität und Wiederverwendbarkeit von Code sind zwei der Hauptvorteile objektorientierter Programmiersprachen, wie wir gleich sehen werden.
Objective-C, Cocoa und Cocoa Touch
Entwickler, die neu in den iOS- und OS X-Ökosystemen sind, werden häufig durch die Beziehung zwischen Objective-C, Cocoa (OS X) und Cocoa Touch (iOS) verwirrt. Was ist Cocoa Touch und in welcher Beziehung steht es zu Objective-C? Cocoa ist Apples native API (Application Programming Interface) für die iOS- und OS X-Plattformen. Ziel-C ist die Sprache, die Kakao antreibt. Während sich dieser Artikel hauptsächlich auf die Programmiersprache Objective-C konzentriert, werden wir uns die APIs Cocoa und Cocoa Touch später in dieser Reihe genauer ansehen.
Klassen, Objekte und Instanzen
Ein weiterer Stolperstein für Entwickler, die neu in der objektorientierten Programmierung sind, ist die Unterscheidung zwischen Klassen, Objekten und Instanzen. Eine Klasse ist eine Besetzung oder Blaupause zum Erstellen von Objekten, während Instanzen eindeutige Vorkommen einer Klasse sind. Ein Objekt ist eine Datenstruktur, die einen Status und ein Verhalten aufweist. Trotz des subtilen Unterschieds zwischen Objekten und Instanzen werden beide Begriffe häufig synonym verwendet.
Schauen wir uns ein Beispiel an: Toaster. Bevor ein Toaster hergestellt wird, erstellen die Ingenieure einen Entwurf, der einer Klasse entspricht. Jeder aus dem Entwurf erstellte Toaster ist eine Instanz oder ein eindeutiges Vorkommen der Klasse. Obwohl jeder Toaster aus derselben Blaupause (Klasse) erstellt wurde, hat jeder seinen eigenen Status (Farbe, Anzahl der Steckplätze usw.) und sein eigenes Verhalten.
Instanzvariablen und Kapselung
Der Status einer Instanz wird in ihren Instanzvariablen oder, wenn Sie so wollen, in den Attributen des Objekts gespeichert und definiert. Dies bringt uns zu einem anderen Schlüsselmuster der objektorientierten Programmierung: der Kapselung. Kapselung bedeutet, dass die interne Darstellung eines Objekts privat ist und nur dem Objekt selbst bekannt ist. Dies scheint auf den ersten Blick eine schwerwiegende Einschränkung zu sein. Das Ergebnis ist jedoch modularer und lose gekoppelter Code.
Lassen Sie uns die Kapselung anhand eines anderen Beispiels veranschaulichen. Die Geschwindigkeit eines Autos wird an den Innenteilen des Autos gemessen, der Fahrer erkennt jedoch die Geschwindigkeit des Autos anhand des Tachometers. Der Fahrer muss die Innenteile des Fahrzeugs nicht kennen oder verstehen, um die Geschwindigkeit des Fahrzeugs zu ermitteln. Ebenso muss der Fahrer des Autos nicht verstehen, wie Motoren funktionieren, um das Auto fahren zu können. Die Details der Funktionsweise eines Autos sind dem Fahrer verborgen. Der Zustand und das Verhalten des Fahrzeugs sind dem Fahrer verborgen und über die Benutzeroberfläche des Fahrzeugs (Lenkrad, Bremspedal, Armaturenbrett usw.) zugänglich.
Vererbung
Ein weiteres mächtiges Paradigma der objektorientierten Programmierung ist die Klassenvererbung. Wenn Klasse A eine Unterklasse der Klasse B ist, erbt Klasse A die Attribute und das Verhalten der Klasse B. Klasse B wird als übergeordnete Klasse oder Oberklasse der Klasse A bezeichnet. Die Vererbung fördert auch die Wiederverwendbarkeit und Modularität des Codes.
Methoden und Eigenschaften
Methoden sind Unterprogramme, die einer Klasse zugeordnet sind und das Verhalten einer Klasse und ihrer Instanzen definieren. Die Methoden einer Klasse haben Zugriff auf die Interna einer Instanz und können dadurch den Status der Instanz ändern. Mit anderen Worten wird der Zustand einer Instanz (d. h. der Instanzvariablen) durch die Methoden einer Instanz (d. h. die Instanzmethoden) gesteuert.
Aufgrund des Kapselungsmusters kann nicht frei auf die Instanzvariablen einer Klasseninstanz zugegriffen werden. Stattdessen wird auf sie über Getter und Setter zugegriffen, Methoden mit dem alleinigen Zweck, Instanzvariablen abzurufen und festzulegen. Eigenschaften sind eine Funktion von Objective-C, die die Erstellung von Accessoren (Getter und Setter) trivial macht. Trotz der Nützlichkeit von Zugriffsmethoden wird es schnell umständlich, Zugriffsmethoden für jede Instanzvariable zu schreiben. Wir werden die Eigenschaften später in diesem Artikel genauer untersuchen. Betrachten Sie Eigenschaften vorerst als Wrapper für Instanzvariablen, die das Arbeiten mit Instanzvariablen über Getter und Setter erleichtern.
Mit gutem Beispiel lernen
Lassen Sie uns unser Wissen in die Praxis umsetzen, indem wir ein neues Xcode-Projekt erstellen, mit dem wir arbeiten können. Erstellen Sie ein neues Projekt in Xcode, indem Sie im Menü Datei die Option Neu > Projekt ... auswählen.



Wählen Sie wie im vorherigen Artikel die Projektvorlage des Befehlszeilen-Werkzeugs in der Kategorie Anwendung im Abschnitt OS X aus.



Setzen Sie den Produktnamen auf Bücher und geben Sie dem Projekt einen Organisationsnamen und eine Firmenkennung. Für dieses Projekt ist es wichtig, den Projekttyp auf Foundation festzulegen. Der Grund für diese Wahl wird später in diesem Artikel klar.



Teilen Sie Xcode mit, wo Sie das Projekt speichern möchten, und klicken Sie auf die Schaltfläche Erstellen. Möglicherweise stellen Sie fest, dass das Projekt anders aussieht als das Projekt, das wir zum Lernen von C erstellt haben. Nehmen wir uns einen Moment Zeit, um die Unterschiede zu erkennen.



Projektübersicht
Das Projekt enthält einige Dateien und Ordner mehr als das Befehlszeilen-Werkzeug, das wir im vorherigen Artikel erstellt haben. Neben main.m und Books.1 gibt es zwei neue Ordner, Unterstützende Dateien und Frameworks, die jeweils ein Element enthalten.
Unterstützende Dateien enthält eine Datei mit dem Namen Books-Prefix.pch. Die Dateierweiterung .pch gibt an, dass es sich um eine vorkompilierte Headerdatei handelt. Sein Zweck wird später in dieser Reihe klar werden.
Der Ordner Frameworks enthält die Frameworks, mit denen das Projekt verknüpft ist. Was ist ein Framework? Ein Framework ist ein Bundle oder Verzeichnis, das eine Bibliothek einschließlich ihrer Ressourcen wie Bilder und Header-Dateien enthält. Das Konzept einer Header-Datei wird in nur einer Minute klar. Der Frameworks-Ordner enthält derzeit ein Element, Foundation.framework.
Beim Erstellen des Projekts setzen Sie den Projekttyp auf Foundation. Dies bedeutet, dass das Projekt mit dem Foundation-Framework verknüpft ist. Das Foundation-Framework ist eine grundlegende Gruppe von Objective-C-Klassen. Später in dieser Reihe werden wir uns das Foundation-Framework genauer ansehen.
Erstellen Sie eine Klasse
Es ist Zeit, Ihre erste Klasse zu erstellen. Wenn Sie eine neue Datei erstellen (Datei > Neu > Datei ...), wird eine Liste mit Dateivorlagen angezeigt. Wählen Sie im Abschnitt OS X die Option Cocoa aus und wählen Sie die Objective-C-Klasse-Vorlage aus, um eine neue Objective-C-Klasse zu erstellen. Klicken Sie Weiter, um fortzufahren.



Geben Sie der neuen Klasse den Namen Book und setzen Sie ihre Unterklasse auf NSObject. Wie wir zuvor gesehen haben, erbt die neue Klasse die Attribute und das Verhalten von NSObject, indem sie die neue Klasse zu einer Unterklasse von NSObject macht. Dies bedeutet, dass die neue Book-Klasse einige Funktionen kostenlos erhält.



Klicken Sie auf Weiter, um fortzufahren und Xcode mitzuteilen, wo Sie die neue Klasse speichern möchten. Stellen Sie sicher, dass Sie die neue Klasse irgendwo in Ihrem Xcode-Projekt speichern.
Xcode hat dem Projekt zwei neue Dateien hinzugefügt, Book.h und Book.m. Book.h ist die Header-Datei der Book-Klasse und macht die Klassenschnittstelle verfügbar, wie wir zuvor gesehen haben. Eine Klassenschnittstelle enthält die Eigenschaften und Methoden der Klasse und gibt auch die Oberklasse der Klasse an. Book.m ist die Implementierungsdatei der Klasse und definiert ihr Verhalten durch Implementieren der in der Klassenheaderdatei deklarierten Methoden.
Header-Datei
Öffnen Sie Book.h und erkunden Sie den Inhalt. Abgesehen von einigen Kommentaren oben enthält die Header-Datei nur drei Codezeilen. In der ersten Zeile wird die Header-Datei des Foundation-Frameworks importiert. Dadurch wird sichergestellt, dass die Book-Klasse Zugriff auf die im Foundation-Framework deklarierten Klassen und Protokolle hat.
1 |
#import <Foundation/Foundation.h>
|
Die zweite und dritte Zeile bilden ein Paar. In Objective-C beginnt jede Klassenschnittstelle mit @interface und endet mit @end, beides Compiler-Direktiven, d.h. Befehle oder Anweisungen für den Compiler. Auf die @interface-Direktive folgen der Name der Klasse, ein Doppelpunkt und gegebenenfalls die Oberklasse der Klasse. Wie wir zuvor gesehen haben, ist die übergeordnete Klasse oder Oberklasse die Klasse, von der sie Attribute und Verhalten erbt.
1 |
@interface Book : NSObject |
2 |
@end
|
NSObject ist die Stammklasse der meisten Objective-C-Klassen. Die ersten beiden Buchstaben, NS, beziehen sich auf seine Ursprünge, NeXTSTEP, wie wir weiter oben in diesem Artikel gesehen haben. Durch das Erben von NSObject verhalten sich Klassen wie Objective-C-Klassen und erben eine grundlegende Schnittstelle zum Laufzeitsystem.
Implementierungsdatei
Bevor wir Änderungen an der Book-Klasse vornehmen, werfen wir einen kurzen Blick auf Book.m, die Implementierungsdatei der Klasse. Anstatt das Foundation-Framework zu importieren, importiert die Implementierungsdatei die Header-Datei der Book-Klasse. Warum ist das notwendig? Die Implementierungsdatei muss wissen, welche Eigenschaften und Methoden in der Headerdatei deklariert sind, bevor sie das Verhalten (d. h. Methoden) der Klasse implementieren kann. Auf die import-Anweisung folgt die Implementierung der Klasse, angegeben durch @implementation und @end.
Eigenschaften und Methoden hinzufügen
Die Book-Klasse ist in ihrer aktuellen Implementierung nicht sehr nützlich. Gehen Sie zur Header-Datei, fügen Sie drei year-Eigenschaften, title und author hinzu und fügen Sie eine Methode mit dem Namen bookInfo hinzu.
Eigenschaften werden mit dem Schlüsselwort @property deklariert und können an einer beliebigen Stelle im @interface-Block der Klasse deklariert werden. Auf das Schlüsselwort @property folgen der Typ und der Name der Eigenschaft. Vergessen Sie nicht das Sternchen vor den title- und author-Eigenschaften, da ein Cocoa-Objekt immer als Zeiger referenziert wird.
1 |
#import <Foundation/Foundation.h>
|
2 |
|
3 |
@interface Book : NSObject |
4 |
|
5 |
@property int year; |
6 |
@property NSString *title; |
7 |
@property NSString *author; |
8 |
|
9 |
- (NSString *)bookInfo; |
10 |
|
11 |
@end
|
Die Methodendeklaration ähnelt leicht einem Funktionsprototyp, es gibt jedoch eine Reihe von wesentlichen Unterschieden. Die Methodendeklaration beginnt mit einem Minuszeichen, das angibt, dass es sich um eine Instanzmethode handelt. Klassenmethoden wird ein Pluszeichen vorangestellt. Auf das Minuszeichen folgt der Rückgabetyp der Methode zwischen Klammern, eine Instanz von NSString und der Name der Methode. Die Methodendeklaration endet mit einem Semikolon.
Ich bin sicher, Sie fragen sich, was NSString ist und warum es als Zeiger referenziert werden muss. Die NSString-Klasse ist Mitglied des Foundation-Frameworks. Es deklariert die Schnittstelle für ein Objekt, das eine unveränderliche Zeichenfolge verwaltet. Im vorherigen Artikel haben wir gesehen, dass eine Zeichenfolge in C durch ein Array von Zeichen dargestellt werden kann. Genau das tut die NSString-Klasse. Sie verwaltet ein Array von Zeichen unter der Haube. Der Vorteil der Verwendung von NSString besteht darin, dass die Arbeit mit Zeichenfolgen erheblich vereinfacht wird.
BookInfo implementieren
Nachdem wir die bookInfo-Methode in der Header-Datei der Klasse deklariert haben, ist es Zeit, sie in der Implementierungsdatei der Klasse zu implementieren. Öffnen Sie Book.m und fügen Sie das folgende Code-Snippet irgendwo im @implementation-Block hinzu. Bevor wir die Implementierung von bookInfo abbrechen, müssen wir zunächst über Objektnachrichten sprechen.
1 |
- (NSString *)bookInfo { |
2 |
NSString *bookInfo = [NSString stringWithFormat:@"%@ was written by %@ and published in %i", self.title, self.author, self.year]; |
3 |
return bookInfo; |
4 |
}
|
Objektnachrichten
Wir wissen bereits, dass das Verhalten einer Klasse durch ihre Methoden definiert wird. Um eine Methode für ein Objekt aufzurufen, wird eine Nachricht an das Objekt gesendet. Überprüfen Sie das folgende Codefragment, um dieses Konzept zu verstehen. Lassen Sie es uns Zeile für Zeile aufschlüsseln. In der ersten Zeile deklarieren wir eine neue Zeichenfolge und weisen ihr eine konstante Zeichenfolge zu, indem wir die Zeichenfolge in doppelte Anführungszeichen setzen und ihr ein @-Zeichen voranstellen.
1 |
NSString *string = @"This is a string of characters."; |
2 |
int length = [string length]; |
3 |
NSLog(@"The length of the string is %i.\n" length); |
In der zweiten Zeile senden wir eine Nachricht mit length an die Zeichenfolgeninstanz. Mit anderen Worten, wir rufen die length-Methoden für die Zeichenfolgeninstanz auf und die Methode gibt eine Ganzzahl zurück. Die Ganzzahl wird der length-Variablen vom Typ int zugewiesen. In der letzten Zeile protokollieren wir die Längenvariable in der Konsole, indem wir die NSLog-Funktion aufrufen, wie wir im vorherigen Artikel gesehen haben.
Das Senden von Nachrichten an Objekte ist etwas, das Sie häufig tun werden. Daher ist es wichtig, die Syntax zu verstehen. Auch wenn die Syntax seltsam aussieht, wenn Sie mit Objective-C noch nicht vertraut sind, ist sie nicht so schwer zu verstehen. In eckigen Klammern steht links das Objekt und rechts der Name der Nachricht oder Methode.
1 |
[object message]; |
Methoden, die Argumente akzeptieren, sehen etwas anders aus, aber die allgemeine Syntax ist identisch. Die NSString-Klasse verfügt beispielsweise über eine andere Methode namens substringFromIndex:. Der Doppelpunkt am Ende des Namens gibt an, dass diese Methode ein Argument akzeptiert. Das Aufrufen dieser Methode für eine Zeichenfolge sieht folgendermaßen aus:
1 |
NSString *substring = [string substringFromIndex:5]; |
Objective-C ist bekannt für seine langen und ausführlichen Methodennamen. Schauen Sie sich das folgende Beispiel an, das einen Methodennamen mit mehreren Argumenten enthält. Sie müssen zugeben, dass der Name der Methode eindeutig angibt, was die Methode tut. Der Methodenname wird in Blöcke aufgeteilt, wobei jeder Block ein Argument akzeptiert. Sobald wir mit dem iOS SDK arbeiten, werden die Objektnachrichten wirklich eingesetzt.
1 |
NSString *anotherString = [string stringByPaddingToLength:5 withString:@"some string" startingAtIndex:2]; |
Bevor wir fortfahren, müssen wir die Implementierung von bookInfo erneut überprüfen. Die Methodenimplementierung beginnt mit der Wiederholung der Methodendeklaration. Das nachfolgende Semikolon wird durch ein Paar geschweifte Klammern ersetzt, die die Implementierung der Methode umschließen. Wir deklarieren zuerst eine neue Zeichenfolge, bookInfo, und weisen ihr eine neue Zeichenfolge zu, die mit den Attributen unserer Buchinstanz (title, author und year) erstellt wurde. Am Ende der bookInfo-Methode geben wir die neue Zeichenfolge bookInfo zurück, da die Methode dies erwartet, eine Zeichenfolge als Rückgabetyp.
Drei Dinge bedürfen einer Klärung. Erstens ist die Methode stringWithFormat: eine Klassenmethode und keine Instanzmethode. Wir wissen dies, weil die Methode für die Klasse selbst, NSString, und nicht für eine Instanz der Klasse aufgerufen wird. Klassenmethoden sind in objektorientierten Programmiersprachen üblich. Zweitens wird der Formatbezeichner für ein Objekt durch das @-Symbol dargestellt (vor dem Prozentzeichen). Sowohl title als auch author sind Objekte - Zeichenfolgen, um genau zu sein. Drittens verweist das Schlüsselwort self immer auf die Klasseninstanz. In diesem Fall bezieht sich self auf die Book-Instanz, zu der die Methode bookInfo gehört.
Accessors überarbeitet
Wenn Sie mit anderen objektorientierten Sprachen gearbeitet haben, kann der Zugriff auf Instanzvariablen in Objective-C verwirrend sein. Wir greifen nicht direkt auf eine Instanzvariable zu, wenn wir self.title schreiben. Dies ist nichts weiter als eine Verknüpfung für [self title]. Letzteres bedeutet, dass wir die Getter-Methode verwenden, um die Instanz nach der Instanzvariablen mit dem Namen title zu fragen. Gleiches gilt für das Setzen einer Instanzvariablen. Schauen Sie sich das folgende Code-Snippet an. Wie Sie sehen können, ist die Verwendung von self.title nichts anderes als syntaktischer Zucker.
1 |
// This assignment ...
|
2 |
self.title = @"The Hobbit"; |
3 |
// ... is equivalent to ...
|
4 |
[self setTitle:@"The Hobbit"]; |
id, nil und NULL
id
Bevor wir die Book-Klasse verwenden, möchte ich einige Schlüsselwörter ansprechen, die die Leute von Zeit zu Zeit verwirren. Wenn Sie ein Objekt speichern möchten, ohne den Typ dieses Objekts explizit zu definieren, verwenden Sie den id-Datentyp, der auch der Standardtyp für Rückgabe- und Argumentdeklarationen für Objective-C-Methoden ist.
Die Leistung und Nützlichkeit des id-Datentyps geht jedoch noch viel weiter. Der id-Datentyp ist eine Schlüsselkomponente der dynamischen Typisierung und dynamischen Bindung von Objective-C. Es ist wichtig zu verstehen, dass der id-Datentyp keine Informationen über das Objekt selbst enthält, außer dass es sich um ein Objekt handelt.
In Objective-C weiß jedes Objekt, zu welcher Klasse es gehört (über eine isa-Variable), und dies ist kritisch. Warum ist das so? Eine der Stärken von Objective-C ist die dynamische Typisierung. Dies bedeutet, dass die Typprüfung zur Laufzeit statt zur Kompilierungszeit durchgeführt wird.
Da der id-Datentyp dem Compiler jedoch nichts über die Klasse sagt, zu der das Objekt gehört, muss das Objekt selbst diese Informationen dem Compiler zur Verfügung stellen.
Beachten Sie, dass es durchaus akzeptabel ist, ein Objekt in Objective-C statisch einzugeben, indem Sie die Klasse eines Objekts explizit angeben, anstatt den Datentyp id zu verwenden.
Dynamische Bindung
Dies bringt uns zu einer weiteren wichtigen Komponente der Objective-C-Laufzeit, der dynamischen Bindung. In Objective-C besteht ein wichtiger Unterschied zwischen Funktionen und Nachrichten darin, dass eine Nachricht und das empfangende Objekt erst zur Laufzeit miteinander verbunden werden.
Was bedeutet das und warum ist das wichtig? Dies bedeutet, dass die als Antwort auf eine an ein Objekt gesendete Nachricht aufgerufene Methode zur Laufzeit bestimmt wird, wenn sowohl die Nachricht als auch das Objekt bekannt sind. Dies wird als dynamische Bindung bezeichnet.
nil und NULL
In Objective-C ist das Schlüsselwort nil als null-Objekt definiert, d.h. als id mit dem Wert 0. Unter der Haube gibt es keinen Unterschied zwischen nil, Nil und NULL, und es ist möglich, Nachrichten an zu senden jeder von ihnen wird ausnahmslos geworfen.
Die Konvention besteht darin, nil für Objekte, Nil für Klassen und andernfalls NULL zu verwenden. Das Senden von Nachrichten an nil, Nil und NULL hat Vorteile, aber auch Nachteile. Weitere Informationen zu nil, Nil und NULL finden Sie in dieser Frage zum Stapelüberlauf.
Objekte erstellen
Öffnen Sie main.m und fügen Sie eine import-Anweisung hinzu, um die Header-Datei der Book-Klasse zu importieren. Anstatt spitze Klammern zu verwenden, verwenden wir doppelte Anführungszeichen, um die Header-Datei der Book-Klasse zu importieren. Für lokale Dateien werden doppelte Anführungszeichen verwendet, während für globale Includes spitze Klammern verwendet werden, wobei der Include-Pfad des Projekts verwendet wird.
1 |
#import <Foundation/Foundation.h>
|
2 |
#import "Book.h"
|
Fügen Sie unmittelbar unter dem NSLog-Aufruf das folgende Snippet hinzu, um eine Instanz der Book-Klasse zu erstellen.
1 |
Book *book1 = [[Book alloc] init]; |
2 |
book1.title = @"The Hobbit"; |
3 |
book1.author = @"JRR Tolkien"; |
4 |
book1.year = 1937; |
In der ersten Zeile deklarieren wir eine Variable vom Typ Book und initialisieren sie. Dies ist ein gutes Beispiel, um verschachtelte Methodenaufrufe zu veranschaulichen. Die erste Methode, die für die Book-Klasse aufgerufen wird, ist alloc. Die Details dieses Aufrufs sind nicht wichtig. Das Wesentliche ist, dass Speicher für das neue Objekt allocated und das Objekt erstellt wird.
Aufgrund der Verschachtelung der Aufrufe wird die init-Methode für das neue Objekt aufgerufen, das von der alloc-Methode erstellt wurde. Die init-Methode initialisiert das neue Objekt, richtet das Objekt ein und macht es einsatzbereit. Die init-Methode gibt die Instanz zurück und weist sie in unserem Beispiel der Variablen book1 zu.
Die nächsten drei Zeilen sollten inzwischen bekannt sein. Wir legen Titel, Autor und Erscheinungsjahr des neuen Buches fest.
Erstellen wir ein weiteres Buch und fügen beide Bücher einem Objective-C-Array hinzu. Die Erstellung des zweiten Buches ist nicht neu. Der einzige Unterschied besteht darin, dass wir die Setter der Klasse explizit verwendet haben, um die Instanzvariablen der neuen Instanz festzulegen.
1 |
Book *book2 = [[Book alloc] init]; |
2 |
[book2 setTitle:@"The Fellowship of the Ring"]; |
3 |
[book2 setAuthor:@"JRR Tolkien"]; |
4 |
[book2 setYear:1954]; |
5 |
|
6 |
NSArray *books = [[NSArray alloc] initWithObjects:book1, book2, nil]; |
In der letzten Zeile erstellen wir eine Instanz von NSArray, einer weiteren Klasse des Foundation-Frameworks. Die NSArray-Klasse ist ein Array, in dem eine geordnete Liste von Objekten gespeichert werden kann. Genau wie bei den Buchinstanzen weisen wir Speicher zu und initialisieren das neue Array.
Anstatt init aufzurufen, rufen wir initWithObjects: auf. initWithObjects: ist ein ausgewiesener Initialisierer. Dies bedeutet, dass es sich um eine init-Methode mit einigen zusätzlichen Schnickschnack handelt, um die Objektinitialisierung zu erleichtern.
initWithObjects: Akzeptiert eine beliebige Anzahl von Objekten, die Sie im Array speichern möchten. Die Liste der Objekte sollte immer mit nil enden.
Mischen von C und Objective-C
Ich habe bereits mehrmals erwähnt, dass Objective-C eine strikte Obermenge von C ist und dass wir C und Objective-C frei kombinieren können. Mal sehen, wie das funktioniert. Wir beginnen mit einer einfachen if/else-Anweisung, um zu überprüfen, ob das Array Objekte enthält. Durch Senden einer Zählnachricht an das Array wird count der darin enthaltenen Objekte zurückgegeben.
Wenn das Array Objekte enthält, verwenden wir eine for-Schleife, um die Objekte im Array zu durchlaufen. Während jeder Iteration fragen wir das Array nach dem Objekt am Index i und senden dem Objekt - einer Instanz der Book-Klasse - eine Nachricht von bookInfo. Wie wir bereits gesehen haben, gibt bookInfo eine Instanz von NSString zurück, die wir an der Konsole protokollieren.
1 |
if ([books count] > 0) { |
2 |
for (int i = 0; i < [books count]; i++) { |
3 |
Book *aBook = [books objectAtIndex:i]; |
4 |
NSLog(@"%@", [aBook bookInfo]); |
5 |
}
|
6 |
}
|
Schlussfolgerung
Ich bin sicher, dass Sie von Objective-C ein wenig überwältigt sind. Das ist normal. Obwohl Objective-C nichts weiter als eine dünne Schicht über der C-Sprache ist, ist ziemlich viel los.
Während Objective-C mehr beinhaltet als in diesem Artikel beschrieben, kennen Sie jetzt die Grundlagen und können mit dem iOS SDK arbeiten. Im nächsten Artikel werden wir uns das iOS SDK ansehen und seine verschiedenen Komponenten untersuchen.



