Modern Objective-C und Cocoa

Programmierung für Mac OS X und iPhone

Holger Hinzberg

Teil III: iOS-Anwendungen für iPhone & Co

In diesem Teil:

Teil II: Cocoa-Anwendungen

In diesem Teil:

Teil I: Grundlagen von Objective-C

In diesem Teil:

Impressum

Bibliografische Information der Deutschen Nationalbibliothek

Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über <http://dnb.d-nb.de> abrufbar.

ISBN 978-3-8266-9908-6

3. Auflage 2014

www.mitp.de

E-Mail: kundenservice@hjr-verlag.de

Telefon: +49 6221 / 489 -555

Telefax: +49 6221 / 489 -410

© 2014 mitp, eine Marke der Verlagsgruppe Hüthig Jehle Rehm GmbH Heidelberg, München, Landsberg, Frechen, Hamburg

Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.

Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.

Lektorat: Sabine Schulz

Korrektorat: Manfred Buchholz

Covergestaltung: © Max Krasnov

electronic publication: III-satz, Husby, www.drei-satz.de

Dieses Ebook verwendet das ePub-Format und ist optimiert für die Nutzung mit dem iBooks-reader auf dem iPad von Apple. Bei der Verwendung anderer Reader kann es zu Darstellungsproblemen kommen.

Der Verlag räumt Ihnen mit dem Kauf des ebooks das Recht ein, die Inhalte im Rahmen des geltenden Urheberrechts zu nutzen. Dieses Werk, einschließlich aller seiner Teile, ist urheberrechtlich geschützt. Jede Verwertung außerhalb der engen Grenzen des Urheherrechtsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen und Einspeicherung und Verarbeitung in elektronischen Systemen.

Der Verlag schützt seine ebooks vor Missbrauch des Urheberrechts durch ein digitales Rechtemanagement. Bei Kauf im Webshop des Verlages werden die ebooks mit einem nicht sichtbaren digitalen Wasserzeichen individuell pro Nutzer signiert.

Bei Kauf in anderen ebook-Webshops erfolgt die Signatur durch die Shopbetreiber. Angaben zu diesem DRM finden Sie auf den Seiten der jeweiligen Anbieter.

Anhang B: Glossar

Accessor-Methoden

Da alle Instanzvariablen einer Klasse privat sind, können sie von außerhalb der Klasse nicht angesprochen oder manipuliert werden. Abhilfe schaffen Accessor-Methoden​, deren Aufgabe darin besteht, den Zugriff auf die Instanzvariablen über Methoden zu ermöglichen und zu regulieren. Da innerhalb einer Accessor-Methode beliebiger Objective-C-Code ausgeführt werden kann, ist eine Überprüfung von zugewiesenen Werten mit geringem Aufwand möglich. In vielen Situationen treten Accessor-Methoden als Paar auf, wobei eine Methode zum Lesen der Instanzvariable (Getter​) dient und eine weitere Methode zum Schreiben in die Variable (Setter​).

Automatic Reference Counting

Verwendet ein Programm ARC, dann werden die retain- und release-Anweisungen zur Speicherverwaltung von Objekten selbstständig vom Compiler in den Programmcode eingefügt. In der Vergangenheit mussten diese noch vom Entwickler selbst eingegeben werden. Attribute wie weak und strong bestimmen bei Eigenschaften, wie Objekte aufeinander verweisen und ob sie sich gegenseitig »festhalten«.

awakeFromNib

Objekte erhalten automatisch die Nachricht awakeFromNib​, nachdem die grafische Oberfläche der Anwendung erfolgreich aus einer nib-Datei geladen und aufgebaut wurde. Im Gegensatz zur init-Methode sind beim Aufruf von awakeFromNib die IBOutlet im Programmcode mit den Steuerelementen der Oberfläche verbunden, sodass dann vom Code aus Manipulationen und Anpassungen der Oberfläche stattfinden können. Daher, und durch den automatischen Aufruf, eignet sich awakeFromNib gut, um beim Programmstart weitere Initialisierungen durchzuführen.

Code Sense

Code Sense​ ist eine Hilfe des Xcode-Texteditors, bei der schon während der Eingabe Methodennamen und Parameter vorgeschlagen werden. Somit werden Schreibfehler verhindert und der Entwickler muss nicht mehr alle Methodennamen komplett auswendig lernen.

Convenience Allocator

Convenience Allocators dienen zur vereinfachten Instanziierung von Objekten, da sie die Aufgaben der Anweisungen alloc und init in einem einzelnen, oft kurzen Befehl zusammenfassen. Für Objekte, die auf diese Weise erzeugt werden, ist keine release-Anweisung erforderlich, denn per Convenience Allocator erzeugte Objekte werden immer dem Autorelease Pool hinzugefügt.

Debugger

Der Debugger​ ist ein in Xcode integriertes Werkzeug zur Fehlersuche, welches es dem Entwickler ermöglicht, die Anweisungen im Programm Schritt für Schritt abarbeiten zu lassen. Außerdem erlaubt es der Debugger, die Werte von Variablen und Objekten zur Laufzeit anzuzeigen und zu verändern.

Delegate

Der Begriff Delegate​ beschreibt ein Hilfsobjekt, welches einem anderen Objekt zur Seite gestellt wird, um bestimmte Aufgaben zu erfüllen oder um auf genau definierte Nachrichten zu reagieren. Das Entwurfsmuster der Delegation wird verwendet, um eine existierende Klasse auch ohne Vererbung um zusätzliche Funktionalität zu erweitern. Sehr oft wird auch der Zeiger, die Instanzvariable, über den das Hilfsobjekt mit dem Objekt verbunden wird, mit delegate bezeichnet.

Eigenschaften

Durch die mit Objective-C 2.0 eingeführten Eigenschaften oder Properties, können in vielen Fällen die von Hand programmierten Accessor-Methoden durch vom Compiler generierte Getter und Setter ersetzt werden. Neben der verkürzten Deklaration ermöglichen Properties die aus anderen Programmiersprachen bekannte Schreibweise der Punktnotation, bei der auf eine Eigenschaft über den Objektnamen, gefolgt von einem Punkt und dem Eigenschaftennamen, zugegriffen werden kann.

Beispiel: aPerson.name = @"Meier";

Factory-Methode

Factory-Methoden werden verwendet, um neue Instanzen einer bestimmten Klasse anzulegen. Die zur Instanziierung benötigten Anweisungen alloc, init oder new werden dabei innerhalb der Methode ausgeführt. Zusätzlich übernehmen Factory-Methoden oftmals die Aufgabe, für das neu angelegte Objekt Startwerte zu setzen und somit ein vollständig vorbereitetes Objekt abzuliefern. Factory-Methoden sind meistens Klassenmethoden, weil zum Zeitpunkt der Ausführung noch kein Objekt der Klasse existiert, das als Nachrichtenempfänger dienen könnte.

Forward Declaration

Eine Forward Declaration mit @class Klassenname ist ein Versprechen an den Compiler, dass im Projekt eine Klasse mit dem angegebenen Namen definiert ist, ohne dass er sie bereits zu diesem Zeitpunkt laden muss. @class wird eingesetzt, um den Import von Header-Dateien in andere Header zu vermeiden und somit die Kompilierungszeit zu verringern.

Framework

In der Softwareentwicklung versteht man unter einem Framework​ den Zusammenschluss von mehreren Klassen und anderen Programmstrukturen zu einer gemeinsamen Bibliothek. Die in diesem Buch verwendeten Frameworks sind hauptsächlich das Foundation Framework mit Klassen wie NSObject, NSArray oder NSKeyedArchiver sowie die beiden Frameworks Application Kit und UIKit für die grafischen Oberflächen von OS-X- und iOS-Anwendungen.

Haltepunkt

Ein Haltepunkt (englisch: Breakpoint) ist eine im Programmcode gesetzte Markierung, welche den Debugger veranlasst, den Programmablauf an einer genau definierten Stelle oder unter bestimmten Bedingungen anzuhalten. Ein durch einen Haltepunkt unterbrochenes Programm kann jederzeit ohne Datenverlust fortgeführt werden.

Header

Der Header, auch Interface genannt, ist das Inhaltsverzeichnis einer Klasse und enthält neben den Instanzvariablen auch die öffentlichen Methodendeklarationen einer Klasse. Zwar müssen nicht alle Methoden einer Klasse zwangsläufig im Header aufgeführt sein, sollen diese aber auch von außerhalb der Klasse aus aufgerufen werden können, ist eine Deklaration im Header empfehlenswert. In Objective-C-Programmen ist der Header einer Klasse immer eine eigenständige Datei mit der Endung .h.

Instanzvariable

Wird eine Variable im Header einer Klasse deklariert, so wird diese als Instanzvariable​ bezeichnet, da sie so lange existiert, wie die Objektinstanz erhalten wird. Instanzvariablen sind innerhalb der gesamten Klasse bekannt und können von allen Methoden uneingeschränkt verwendet werden. Werden von einer Klasse mehrere Objekte instanziiert, wird für jede Instanzvariable ein neuer und eigenständiger Speicherplatz angelegt.

Interface Builder

Der Designer zur Gestaltung grafischer Oberflächen für OS-X- und iOS-Anwendungen wird als Interface Builder bezeichnet und war bis zur Version 3 von Xcode noch ein eigenständiges Programm. Neben dem Design und Layout ermöglicht es der Interface Builder, zusätzliche Objekte zu definieren, die automatisch beim Laden der grafischen Oberfläche instanziiert werden.

Lazy Instantiation

Hinter diesem Begriff verbirgt sich ein Verfahren, bei dem Objektinstanzen erst angelegt werden, wenn sie das erste Mal benötigt werden. So lässt sich der Speicherverbrauch reduzieren, falls ein bestimmtes Objekt zur Laufzeit der Anwendung überhaupt nicht benötigt wird. Die Lazy Instantiation wird oft in den Gettern von Instanzvariablen oder Eigenschaften implementiert, wo bei jedem Aufruf geprüft wird, ob von dem gewünschten Objekt bereits eine Instanz existiert.

MVC-Entwurfsmuster

Das Model-View-Controller-Entwurfsmuster beschreibt die strikte Trennung von Daten (Model), grafischer Oberfläche (View) und Programmlogik (Controller). Wird für eine Anwendung MVC verwendet, gehört jedes Objekt einer der drei Kategorien an.

Nib-Datei

Eine vom Interface Builder erzeuge Datei mit den Objekten und Informationen für eine grafische Programmoberfläche. Nib ist eine Abkürzung für NeXT Interface Builder und lässt auf die lange Geschichte des Interface Builders, beginnend bei der Firma NeXT Computer, schließen. Obwohl neue Projekte eine XML-Version dieser Datei mit der Endung .xib benutzen, wird im normalen Sprachgebrauch weiterhin der Name Nib-Datei​ verwendet.

NSObject

Eltern- oder Superklasse vieler anderer Klassen in den von Apple verwendeten Frameworks. NSObject übernimmt die Aufgabe, Speicherplatz für Objekte bereitzustellen und den Referenzzähler zu verwalten. Von NSObject erben andere Klassen unter anderem die Methoden alloc, init oder new.

Outlet

Als Outlet oder IBOutlet bezeichnet man einen Zeiger, immer als Instanzvariable einer Klasse, über den Objekte miteinander verbunden werden. Der Zeiger verwaltet also nicht ein Objekt, welches in seiner Klasse instanziiert wird, sondern verweist auf ein externes Objekt, das explizit zugewiesen wird. Über ein IBOutlet wird in der Regel ein Zeiger im Programmcode mit einem grafischen Steuerelement, welches aus einer Nib-Datei geladen wird, verbunden.

Präprozessordirektive

Präprozessordirektiven sind keine Befehle der Programmiersprache Objective-C, sondern Anweisungen direkt an den Compiler. Sie werden unter anderem verwendet, um Klassen-Header zu importieren oder bestimmte Bereiche im Programmcode zu markieren. Eine sehr beliebte Präprozessordirektive ist #define, mit der Texte und Anweisungen im Code ersetzt oder entfernt werden können.

Protokoll

In Objective-C bestimmt ein Protokoll​ genau spezifizierte Methoden, welche eine Klasse implementieren muss, sofern diese Methoden nicht durch @optional gekennzeichnet sind. Da Protokolle außerhalb der Vererbungshierarchie stehen, können auch unterschiedlichste Klassen dieselben Protokolle umsetzen und somit auf identische Nachrichten reagieren.

Schema

Ein Schema (englisch: Scheme) beschreibt die Konfiguration des Compilers sowie weitere projektspezifische Einstellungen. Durch die Build Configuration des Schemas kann eine Anwendung als Debug für die Entwicklung oder Release für die Veröffentlichung und Weitergabe an den Endbenutzer kompiliert werden. Die Auswahl der Architektur, 32 Bit oder 64 Bit, ist ebenfalls eine Einstellung des Schemas.

Selektor

Methodennamen, einschließlich ihrer Parameter, werden in Objective-C als Selektor​ bezeichnet. Der Datentyp SEL erlaubt es dabei, Methodenaufrufe an ein Objekt auch erst zur Laufzeit einer Anwendung zu erstellen und zu verarbeiten. Ob ein Objekt auf einen bestimmten Aufruf reagiert, kann mit der Methode respondsToSelector überprüft werden.

Storyboard

In einem iOS-Projekt übernimmt die Storyboard-Datei die Verwaltung sämtlicher grafischer Oberflächen aller View Controller. Waren in der Vergangenheit noch einzelne .xib-Dateien erforderlich, kann mithilfe eines Storyboards erstmalig die komplette Anwendung überblickt werden. Das Storyboard übernimmt dabei zusätzlich die Aufgabe eines Workflows, in dem die Navigation zwischen den einzelnen View Controllern festgelegt wird. Animationen und Übergänge, sogenannte »Segue«, werden ebenfalls im Storyboard konfiguriert.

Target

Das aus einem Xcode-Projekt zu kompilierende Resultat wird als Target bezeichnet und ist in vielen Fällen eine ausführbare Anwendung. Klassenbibliotheken, Frameworks oder andere Programmbausteine können aber ebenfalls Target eines Projekts sein.

Vererbung

Bei der objektorientierten Programmierung ermöglicht es die Vererbung​, die Methoden und Instanzvariablen einer bestehenden Klasse in eine neue Klasse zu übernehmen und somit auf bereits vorhandenen Programmcode aufzubauen. Nahezu alle Klassen erben von NSObject und erhalten somit die Fähigkeit, Speicherplatz für die aus ihnen instanziierten Objekte zu erzeugen. Wäre Vererbung nicht möglich, müsste diese Funktionalität für jede Klasse immer wieder neu implementiert werden.

View

Die grafische Oberfläche einer Anwendung wird als View bezeichnet und beinhaltet alle Objekte, die der Anwender sehen und bedienen kann. Im MVC-Entwurfsmuster ist der View stark von den Programmdaten (Model) abgekapselt und kommuniziert nur mit einem Controller. Eine Schaltfläche existiert dabei unabhängig von der mit ihr verbundenen IBAction-Methode und ein Textfeld hat keinen direkten Bezug zu den angezeigten Daten.

View Controller

Steuert ein Controller keine komplette Anwendung, sondern nur ein Fenster oder eine Ansicht, wird er sehr oft als View Controller bezeichnet. Spezielle Arten von View Controllern wie Navigation Controller oder Tableisten-Controller steuern dabei auch den Übergang zwischen verschiedenen Ansichten.

viewDidLoad

Ähnlich wie das awakeFromNib einer Cocoa-Anwendung wird die Methode viewDidLoad automatisch aufgerufen, wenn die grafische Oberfläche einer iOS-Anwendung geladen wurde.

Xcode

Von Apple angebotene Entwicklungsumgebung (IDE) zur Programmierung von OS-X- und iOS-Anwendungen oder -Bibliotheken. Zu den Neuerungen der 2011 vorgestellten Version 4 zählt unter anderem ein leistungsstärkerer Compiler sowie ein integrierter Interface Builder, der zuvor ein eigenständiges Programm war. Zusätzliche Erweiterungen zur Leistungs- und Qualitätsanalyse wurden mit den nachfolgenden Versionen eingeführt.

Anhang A: Fragen und Antworten

Kapitel 2: Durchstarten mit Xcode 5

  1. Sie möchten auf der Konsole lediglich die Ausgaben des Programms und nicht des Compilers anzeigen. Welche Einstellung ist dafür erforderlich?

    Die Auswahl Target Output beschränkt die Anzeige der Konsole auf ausschließlich vom Programm generierte Ausgaben.

  2. Was ist Code Folding?

    Innerhalb des Texteditors können Blöcke aus geschweiften Klammern zusammengeklappt und ihr Inhalt ausgeblendet werden. Dieser als Code Folding bezeichnete Mechanismus sorgt für eine bessere Übersicht, vor allem bei langem Programmcode.

Kapitel 3: NSLog, Variablen und Format Specifier

  1. Warum ist das @-Zeichen vor Definitionen einer NSString-Zeichenkette erforderlich?

    Da der Compiler auch innerhalb von Objective-C-Projekten Anweisungen der Sprache C akzeptiert, wird das @ verwendet, um die Zeichenketten der beiden Sprachen zu unterscheiden.

  2. Warum sollte man Zeichenketten nicht mit dem Gleichheitsoperator (==) vergleichen?

    Werden Objekte – und dazu gehören auch Zeichenketten vom Typ NSString – mit dem Gleichheitsoperator verglichen, so ist dies keine Prüfung der Texte, sondern lediglich ein Vergleich der verwendeten Speicheradressen.

  3. Die Aufgabe lautet, zwei Zeichenketten zu vergleichen und dabei die Groß- und Kleinschreibung zu vernachlässigen. Welche Methode kann dazu verwendet werden?

    Die Methode caseInsensitiveCompare der Klasse NSString erlaubt es, zwei Zeichenketten zu vergleichen und die Groß- und Kleinschreibung dabei zu ignorieren.

Kapitel 4: Klassen und Objekte

  1. Wie viele Objekte können aus einer Klasse instanziiert werden?

    Es gibt keine Obergrenze für die Anzahl möglicher Instanzen und theoretisch können aus einer Klasse beliebig viele Objekte erstellt werden. In der Praxis wird hingegen irgendwann der Arbeitsspeicher des Computers zur Neige gehen und dann keine weiteren Instanzen mehr zulassen.

  2. Wann werden Accessor-Methoden für eine Klasse benötigt?

    Alle Instanzvariablen sind »privat« und können nur innerhalb der Klasse direkt angesprochen werden. Möchte man die Werte der Instanzvariablen auch von außerhalb der Klasse verwenden, funktioniert das nur über Accessor-Methoden mit Getter und Setter.

  3. Mit welcher Anweisung kann die Initialisierung eines Objekts, die sonst mit alloc und init geschieht, abgekürzt werden?

    Die Methode new fasst die beiden Methoden alloc und init in einem Aufruf zusammen.

Kapitel 5: Speicherverwaltung von Objekten

  1. Eine Klasse implementiert eine eigene Methode zur Initialisierung. Was ist dabei zu beachten?

    Verwendet eine Klasse nicht die von NSObject geerbte init-Methode, muss diese Methode der Elternklasse explizit aus der neuen Klasse aufgerufen werden. Andernfalls ist die Objektinitialisierung nicht vollständig.

  2. Welche Aufgabe hat eine Factory-Methode?

    Eine Factory-Methode übernimmt die Aufgabe, neue Objekte einer Klasse zu erzeugen. Oftmals fällt ihr zusätzlich die Aufgabe zu, die Eigenschaften des neu angelegten Objekts auf bestimmte Startwerte zu setzen.

Kapitel 6: Objective-C wird erwachsen

  1. Welche alternative Schreibweise im Programmcode wird durch die Verwendung von Properties möglich?

    Der sogenannte Punktoperator erlaubt den Zugriff auf die Eigenschaften eines Objekts über den Objektnamen, gefolgt von einem Punkt und dem Namen der Eigenschaft. Eckige Klammern, die eigentlich typische Objective-C-Syntax, ist nicht länger erforderlich.

  2. Welchen Nachteil haben Properties gegenüber Accessor-Methoden?

    Da Accessor-Methoden vollwertige Methoden sind, können in ihnen beliebige Objective-C-Anweisungen programmiert werden. Somit erlauben sie auch eine Logik, um die übergebenen Werte zu überprüfen. Properties können das nicht, sie ermöglichen lediglich einen direkten Zugang zu den privaten Instanzvariablen.

Kapitel 7: Der Debugger

  1. Welche Aufgabe haben Haltepunkte?

    Erreicht ein laufendes Programm einen Haltepunkt, so pausiert die Anwendung an dieser Stelle. Jetzt können Variableninhalte und andere programminterne Informationen untersucht werden. Ein durch einen Haltepunkt gestopptes Programm kann jederzeit fortgeführt werden.

  2. Was zeigt der Aufrufstapel?

    Der Aufrufstapel (englisch: Call Stack) ist eine hierarchische Ansicht der bis zum Erreichen eines Haltepunkts aufgerufenen Methoden. Anhand des Aufrufstapels lässt sich schnell erkennen, in welcher Reihenfolge sich Methoden gegenseitig aufgerufen haben.

Kapitel 8: Robuste Anwendungen und automatisierte Tests

  1. Welche Methode in einer Testklasse wird immer automatisch als erste Methode ausgeführt?

    Die Methode setup wird bei einem Test immer als erste Methode aufgerufen.

  2. Welche Klasse kann verwendet werden, um ein Objekt der Klasse NSDate in eine formatierte Zeichenkette umzuwandeln?

    Die Klasse NSDateFormatter kann verwendet werden, um ein Datum in eine Zeichenkette zu konvertieren.

  3. Wie unterscheiden sich die Compiler-Einstellungen Debug und Release?

    Wird ein Projekt mit der Einstellung Debug kompiliert, dann enthält das Programm zusätzliche Informationen, welche die Fehlersuche erleichtern. In der Release-Version fehlen diese Informationen – allerdings läuft die Release-Version oftmals schneller und ist kleiner.

Kapitel 9: Vererbung, Kategorien und Protokolle

  1. Eine neue Klasse soll von einer bereits bestehenden Klasse erben. Wo wird diese Verbindung der beiden Klassen definiert?

    Soll eine Klasse von einer anderen Klasse erben, so muss im Header der Kindklasse der Name der Elternklasse dem Klassennamen in der @interface-Definition folgen. Wird dort kein Name einer Elternklasse festgelegt, erbt die Klasse von NSObject.

  2. Mit welchem Empfänger können Nachrichten innerhalb einer Klasse versendet werden, um zum Beispiel von einer Methode aus eine andere Methode in derselben Klasse aufzurufen?

    Um von einer Methode aus weitere Methoden innerhalb derselben Klasse aufzurufen, ist self der zu verwendende Empfänger.

  3. Mit welchem Empfänger können von einer Kindklasse aus Methoden der Elternklasse aufgerufen werden?

    Nachrichten von einer Kindklasse an seine Elternklasse finden über den Empfänger super ihr Ziel.

  4. Wie können Protokolle bei der Implementierung von Methoden helfen?

    Verpflichtet sich eine Klasse ein Protokoll umzusetzen, muss sie die im Protokoll definierten Methoden implementieren. Fehlen diese oder gibt es Schreibfehler bei den Methodennamen, wird der Compiler Warnungen anzeigen.

Kapitel 10: Array und Dictionary

  1. Wie unterscheiden sich die beiden Klassen NSArray und NSMutableArray?

    Während ein NSArray schon bei der Initialisierung alle zu verwaltenden Objekte erhält, können einem NSMutableArray auch später zur Laufzeit noch weitere Referenzen hinzugefügt werden. Außerdem erlaubt ein NSMutableArray umfangreichere Manipulationen der Auflistung. Objekte können entfernt oder getauscht werden.

  2. Ein Array in Objective-C kann nur Objekte verwalten und ist daher nicht in der Lage, eine Liste aus einfachen Datentypen wie int oder double zu bilden. Welche Klasse bietet in dieser Situation eine Alternative?

    Die Klasse NSNumber erlaubt es, einfache Datentypen in einen Objekttyp umzuwandeln, der dann auch in einem Array verwendet werden kann. Wird später wieder der einfache Typ benötigt, ist eine Rückkonvertierung ebenfalls möglich.

  3. Der Key für ein Dictionary muss immer einmalig sein. Was geschieht, wenn Sie einem NSMutableDictionary ein Objekt mit einem schon vorhandenen Key zuweisen?

    Wird einem NSMutableDictionary ein Objekt mit einem bisher unbekannten Key zugewiesen, wird das Objekt als neuer Eintrag angehängt. Die Verwendung eines schon im Dictionary bekannten Schlüssels ersetzt den vorhandenen Eintrag.

Kapitel 11: Hello Cocoa World – eine Cocoa-Anwendung

  1. Was bewirkt im Interface Builder die Eigenschaft Autosave für ein Fenster?

    Wird für ein Fenster in der Eigenschaft Autosave ein beliebiger Bezeichner eingetragen, speichert die Anwendung selbstständig die Fenstergröße und Position. Wird das Programm zu einem späteren Zeitpunkt neu gestartet, werden die gespeicherten Daten gelesen und das Fenster nimmt seine vorherige Größe und Position ein.

  2. Steuerelemente der grafischen Oberfläche und Programmcode kennen einander nicht und müssen erst mit speziellen »Anschlüssen« verbunden werden. Wie heißen diese?

    Über ein IBOutlet kann ein Zeiger im Programmcode mit einem Objekt auf der grafischen Oberfläche verbunden werden. Ereignisse auf dem View, wie das Anklicken einer Schaltfläche, werden mit einer IBAction an den Controller weitergeleitet.

Kapitel 12: Geometry Calculator – ein kleiner Rechner

  1. Mit welcher Einstellung wird die Textausrichtung eines Textfeldes im Interface Builder bestimmt?

    Über die Eigenschaft Alignment im Attributes Inspector kann die Textausrichtung geändert werden.

  2. Welche Richtlinien helfen beim Design einer grafischen Oberfläche?

    Die Human Interface Guidelines von Apple sind eine bewährte Leitlinie bei der Frage, wie grafische Oberflächen aufgebaut sein sollten. Ein Teil dieser Guidelines, wie zum Beispiel der Abstand von Steuerelementen untereinander, wird durch die Anzeige von Hilfslinien innerhalb des Interface Builders umgesetzt.

  3. Welches Verhalten von Steuerelementen kann mit dem Size Inspector festgelegt werden?

    Außer den Abmessungen und Positionen kann mit dem Size Inspector die automatische Größenanpassung von Steuerelementen bestimmt werden. Ändert der Anwender die Fenstergröße, können sich Steuerelemente den veränderten Abmessungen anpassen und ihre Größe ebenfalls ändern.

Kapitel 13: Hinter den Kulissen

  1. Welche Aufgabe hat die Präprozessoranweisung #define?

    #define bewirkt eine Textersetzung, mit der Zeichenfolgen im Programmcode ersetzt oder entfernt werden können. Diese Ersetzung geschieht, bevor der Code kompiliert wird.

  2. Wie kann das About-Fenster einer Cocoa-Anwendung konfiguriert werden?

    Innerhalb des Projekts lässt sich das About-Fenster nur sehr wenig konfigurieren. Das Symbol im Fenster entspricht automatisch dem Icon des Programms und der angezeigte Text ist in der Datei Credits.rtf hinterlegt.

Kapitel 14: Sprachausgabe und Delegation

  1. Wie kann gewährleistet werden, dass ein Objekt korrekt als Delegate eines anderen Objekts funktioniert?

    Bei der Arbeit mit Delegation werden sehr oft Protokolle verwendet, welche das »Hilfsobjekt« verpflichten, bestimmte Methoden zu implementieren. Somit gibt es für die Objekte eine feste Zusage, auf die gesendeten Nachrichten zu reagieren.

  2. Wie kann ein Steuerelement vom Programmcode aus deaktiviert werden?

    Über die Nachricht setEnabled mit den Parameterwerten TRUE oder FALSE können sämtliche Steuerelemente vom Programmcode aus aktiviert und deaktiviert werden.

Kapitel 15: Hallo Taxi

  1. Ohne weitere Konfiguration sendet ein Schieberegler der Klasse NSSlider keine Nachrichten, während er bewegt wird, sondern erst, nachdem der Vorgang des Schiebens beendet wurde. Welche Eigenschaft muss geändert werden, um auch schon während des Verschiebens Nachrichten zu senden?

    Die Eigenschaft Continuous, die im Interface Builder gesetzt werden kann, veranlasst einen Schieberegler auch schon während des Schiebens Nachrichten zu senden.

  2. Um den aktuellen Wert eines Schiebereglers zu erhalten, ist neben der IBAction nicht zwangsläufig ein IBOutlet zum Steuerelement erforderlich. Über welchen alternativen Wert kann die Einstellung eines NSSlider ermittelt werden?

    Ruft ein Schieberegler-Steuerelement eine IBAction auf, so wird ein Verweis auf das Objekt über den Parameter sender übergeben. Mit dem sender erhält man Zugriff auf alle Objekteigenschaften einschließlich des eingestellten Wertes.

  3. Über welche Eigenschaft eines Kontrollkästchens kann ermittelt werden, ob das Häkchen im Steuerelement gesetzt ist?

    Die Eigenschaft state bestimmt den Status eines Kontrollkästchens. Verglichen werden kann dieser Wert mit der Konstanten NSOnState.

Kapitel 16: Benutzereinstellungen und noch mehr Delegation

  1. Die in einem Protokoll definierten Methoden können optional sein, und somit besteht für eine Klasse keine Verpflichtung, diese zu implementieren. Das kann zu Fehlern führen. Wie kann vor dem Senden einer Nachricht sichergestellt werden, dass der Empfänger über die passende Methode verfügt?

    Mit der Methode respondsToSelector kann überprüft werden, ob ein Objekt auf bestimmte Nachrichten reagiert.

  2. Was ist eine plist?

    Eine Eigenschaftenliste, auch als Property List oder plist bezeichnet, ist eine Textdatei im XML-Format und wird sehr oft zur Konfiguration von Anwendungen und zur Archivierung der Benutzereinstellungen verwendet.

  3. Beim ersten Start verfügt eine Anwendung normalerweise noch nicht über gespeicherte Benutzereinstellungen. Wie können für diesen Fall Standardeinstellungen festgelegt werden?

    Die Methode registerDefaults der Klasse NSUserDefaults erlaubt es, für die Benutzereinstellungen ein Dictionary mit Werten zu setzen. Diese Einstellungen werden automatisch verwendet, sollten keine gespeicherten Daten zur Verfügung stehen.

Kapitel 17: Datenquellen und Tabellen

  1. Eine Klasse soll als Datenquelle einer Tabelle eingesetzt werden. Welches Protokoll kommt dabei zum Einsatz und über welches Outlet werden Steuerelement und Daten verbunden?

    Soll eine Klasse als Datenquelle für eine Tabelle verwendet werden, sollte sie das NSTableViewDataSource-Protokoll umsetzen, denn mit ihm wird sichergestellt, dass alle erforderlichen Methoden implementiert werden. Im Interface Builder lässt sich eine Instanz dieser Klasse dann problemlos mit dem Outlet dataSource der Tabelle verbinden.

  2. Die Methode tableView:objectValueForTableColumn:row: wird von einem NSTableView für jede Zelle einer Tabelle separat aufgerufen. Wie lässt sich innerhalb der Methode ermitteln, welche Zeile und welche Spalte angefordert wird?

    Die Zeilennummer wird über den Parameter row vom Typ NSInteger direkt übertragen, während die Spalte über das NSTableColumn zu ermitteln ist. Hier hilft die Eigenschaft Identifier, die im Interface Builder festgelegt wird. Diese etwas komplizierte Vorgehensweise ist erforderlich, da die Spalten noch während der Laufzeit vom Anwender in eine andere Reihenfolge gebracht werden können.

Kapitel 18: Sortierte Tabellen mit Drag und Drop

  1. Sie möchten Tabellenspalten sortieren und benötigen für die Spaltenüberschriften Bilder mit Pfeilen, um die aktuelle Sortierrichtung anzuzeigen. Wo finden Sie diese Grafiken?

    Über die Methode imageNamed der Klasse NSImage erhält man neben eigenen Bildern aus dem Projekt Zugriff auf eine große Auswahl von Grafiken aus den Frameworks. NSAscendingSortIndicator und NSDescendingSortIndicator sind Pfeile, die sich zur Darstellung der Sortierrichtung in Spaltenüberschriften eignen.

  2. Um Drag und Drop in einer Tabelle zu ermöglichen, muss zunächst ein Typ für die zu ziehenden Daten definiert werden. Wie funktioniert das?

    Mithilfe der registerForDraggedTypes-Methoden kann ein Array mit zulässigen Typen an das Tabellen-Steuerelement übergeben werden. Zur Definition eines solchen Typs genügt eine Zeichenkette vom Typ NSString, die einen eindeutigen Bezeichner abbildet.

Kapitel 19: iOS und Hello World

  1. Wie unterscheiden sich die Ereignisse der iOS-Schaltflächen von denen der Schaltflächen in OS-X-Anwendungen?

    Im Unterschied zur einfachen Klick-Aktion unter OS X ermöglichen Schaltflächen für iOS-Anwendungen verschiedene Aktionen für ein einzelnes Steuerelement. Das Touch Down-Ereignis wird ausgelöst, wenn der Anwender die Schaltfläche berührt, während Touch Down Repeat einem Doppelklick auf die Schaltfläche entspricht. Durch Klicken und Ziehen können noch weitere Aktionen für eine Schaltfläche wie Touch Drag Enter oder Touch Drag Exit ausgelöst werden.

  2. Welche Methode eines View Controllers kann verwendet werden, um zusätzliche Konfigurationen der grafischen Oberfläche zu implementieren?

    Die automatisch aufgerufene Methode viewDidLoad wird häufig verwendet, um Anpassungen an der Oberfläche vorzunehmen. Zum Zeitpunkt ihrer Abarbeitung sind die IBOutlet bereits mit den Steuerelementen verbunden und so können alle Eigenschaften der Steuerelemente vom Programmcode aus angepasst werden.

  3. Textfelder im UIKit Framework verfügen nicht über die Eigenschaften stringValue oder doubleValue. Welche Eigenschaft wird stattdessen verwendet?

    Die Eigenschaft text kommt zum Einsatz, um den Inhalt eines Textfeldes zu setzen.

Kapitel 20: Texteingaben und virtuelle Tastaturen

  1. Über welche Methode lässt sich die virtuelle Tastatur für Eingabefelder vom Typ UITextField ausblenden?

    Erhält ein aktives Eingabefeld die Nachricht resignFirstResponder, wird es seine virtuelle Tastatur ausblenden, da die Nachricht das Steuerelement anweist, nicht länger auf Eingaben zu reagieren.

  2. Wie kann bestimmt werden, ob sich der View einer iOS-Anwendung dem geänderten Seitenverhältnis eines gedrehten Gerätes anpasst?

    Wird ein iOS-Gerät gedreht, erhält der UIViewController der Anwendung eine shouldAutorotateToInterfaceOrientation-Nachricht. Der Rückgabewert dieses Methodenaufrufs vom Typ BOOL bestimmt, ob sich der View der Rotation des Gerätes anpassen soll oder nicht.

Kapitel 21: Storyboards – Mit dem Drehbuch durch die App

  1. In einer Anwendung ist ein View Controller mit mehreren Szenen im Storyboard verbunden. Wie können in der Methode prepareForSegue die verschiedenen Segues unterschieden werden?

    Für eine Segue kann im Attributes Inspector des Interface Builders ein Identifier bestimmt werden. Dieser dient zur eindeutigen Identifizierung im Programmcode.

  2. Mit welcher Methode wird ein View Controller initialisiert, der aus einem Storyboard geladen wird?

    Wird ein View Controller aus einem Storyboard geladen, dann wird bei der Initialisierung die Methode initWithCoder aufgerufen. Die von Xcode in die Klasse eingefügte Methode initWithNibName wird hingegen nicht ausgeführt.

  3. Wann wird für einen View Controller viewDidLoad aufgerufen?

    Die Methode viewDidLoad wird aufgerufen, wenn der View zum ersten Mal angezeigt wird. Wird ein View während der Laufzeit eines Programms niemals angezeigt, wird auch seine viewDidLoad-Methode nicht aufgerufen.

Kapitel 22: CountryDB – eine Länderdatenbank

  1. Wie lässt sich in der Navigationsleiste die Bezeichnung der Schaltfläche Back ändern?

    Die Eigenschaft title im navigationItem eines View Controllers dient zur Beschriftung der Schaltfläche, welche untergeordneten View Controllern die Rückkehr zur vorherigen Ansicht ermöglicht. Sie kann im Interface Builder oder durch Anweisungen im Programmcode gesetzt werden.

  2. Über welche Eigenschaft lässt sich ermitteln, wie viele Objekte sich in einem NSArray oder einen NSMutableArray befinden?

    Der Aufruf von count liefert die aktuelle Anzahl aller Objekte des Arrays.

Kapitel 23: Tableisten-Navigation

  1. Mit welchen Format Specifier kann eine Zahl vom Typ Integer in hexadezimaler Schreibweise ausgegeben werden?

    Der Format Specifier "%x" formatiert Integer in das hexadezimale Format. Ergänzungen, wie zum Beispiel "%08x", erweitern die Formatierung zusätzlich auf 8 Stellen und bei Bedarf automatisch mit führenden Nullen.

  2. Was bewirkt bei der Projektauswahl oder beim Hinzufügen eines Views die Einstellung bei Device?

    Die Eigenschaft Device bestimmt, ob ein Projekt oder ein View für iPhone/iPod Touch oder iPad generiert wird. Da das iPad über ein größeres Display als die anderen iOS-Geräte verfügt, müssen bestimmte Komponenten im Projekt angepasst werden.

  3. Was ist bei der Verwendung der Klasse UIColor zu beachten?

    Im Gegensatz zu einigen anderen Systemen oder zu Grafikprogrammen verwendet UIColor zur Definition der RGB-Farbanteile keine Werte von 0 bis 255, sondern Werte von 0.0 bis 1.0. Sollten fremde Farbwerte übernommen werden, darf man nicht vergessen, diese zunächst umzurechnen.

Kapitel 24: Picker und Animation

  1. Mit welcher Nachricht informiert ein UIPickerView-Steuerelement über Veränderungen der ausgewählten Werte?

    Wurde für ein UIPickerView ein delegate-Objekt bestimmt, wird dort bei jeder Änderung der Auswahl die Methode pickerView:didSelectRow:inComponent: aufgerufen. Die übergebenen Parameter row und component lassen dabei genau erkennen, welcher Wert verändert wurde.

  2. Welche beiden Anweisungen werden benötigt, um eine Animation für Farbe oder Bewegung zu definieren und auszuführen?

    Sämtliche Änderungen der grafischen Oberfläche, die im Programmcode zwischen beginAnimation und commitAnimation stehen, werden für eine Animation verwendet. Der Aufruf von commitAnimation startet die Animation und die Objekte nehmen die zuvor gesetzten Werte von Position oder Farbe an. Diese Änderungen geschehen allerdings nicht augenblicklich, sondern als Animation in der mit setAnimationDuration definierten Zeitspanne.