Programmieren mit Swift - Für macOS und iOS
Programmieren mit Swift - Für macOS und iOS
NSObjectController Teil 1

Vielleicht haben Sie sich inzwischen gefragt, wo denn die versprochene Ersparnis von Programcode geblieben ist. Es gibt zwar jetzt keine Anweisungen mehr, um die Werte auf die Textfelder zu bringen, aber die Befehle für das Binding sind nicht weniger aufwändig.
Zwar können auf die gezeigte Art Model und View verbunden werden, so richtig komfortabel wird Binding aber erst, wenn man es im Interface Builder macht. Entfernen Sie daher zunächst alle Anweisungen im Code, die für das Binding notwendig waren. Auch die Outlet zu den Textfeldern können entfernt werden.

Will man Binding im InterfaceBuilder erstellen, ist die erste große Änderung der Zeitpunkt, an dem die Instanz des Characters erstellt wird. Dies muss schon vor awakeFromNib geschehen, da das Binding im Nib-File geschieht und es dort schon eine Instanz der zu bindenden Klasse benötigt. Der beste Weg ist daher, die init-Methode von MyController zu überschreiben. Überschreiben deshalb, weil die Klasse diese Methode von der Superklasse NSObject erbt und diese auch automatisch ausgeführt wird. Schreibt man aber eine eigene Initialisierung, darf man nicht vergessen, auch die Initialisierung der Superklasse aufzurufen, da dies dann nicht mehr automatisch passiert. Auch der Würfel (Dice) kann in dieser Methode initialisiert werden. Das ist zwar nicht unbedingt nötig, aber wenn man es ebenfalls an dieser Stelle tut, kann man auf die awakeFromNib-Methode komplett verzichten.
- init
{
    if (self = [super init])
    {
        rpgDice = [[Dice alloc] init];
        rpgCharacter = [[Character alloc] init];
    }
    return self;
}
Es gibt im Framework verschiedene Objekte, um Daten aus dem Model mit dem View, also der grafischen Oberfläche zu verbinden. In diesem Projekt sollen nur die Instanzvariablen eines einzelnen Objektes (rpgCharacter) verbunden werden. Für diese Aufgabe benötigen Sie einen NSObjectController. Ziehen Sie so ein Element aus der Palette der Steuerelemente auf das Dokumentenfenster des Interface Builder. Anschliessend sollten Sie es in Character Controller umbenennen.
stacks_image_CB880ADD-D3A9-4CC2-B906-96B21C363A41
Dieser Namen beschreibt die Aufgabe des Controllers schon sehr gut - leider fehlt ihm bisher aber die Information, welches Objekt er kontrollieren soll. Es ist ein Objekt in der Klasse MyController, dort die Eigenschaft rpgCharacter. Die nötigen Einstellungen für diese Verbindungen können Sie im Inspector vornehmen, beginnen Sie mit den Attributen.
Zuerst sollte man dem Controller beibringen, welchen Typ von Klasse er verwalten soll. In diesem Fall die Klasse Character. Dann sollten Sie alle in dieser Klasse zu Verfügung stehenden Keys eintragen. Keys bezieht sich ebenfalls wieder auf Key-Value-Coding und gemeint sind die Namen der Instanzvariablen, in der Klasse Character rpgCharacter. Diese beiden Schritte sind nicht unbedingt nötig, aber es ist sinnvoll es zu tun, da später, bei der Verbindung zu den einzelnen Steuerelementen, dieses Keys vorgeschlagen werden. Denken Sie daran, dass beim Key-Value-Coding ein Schreibfehler schwerwiegende Auswirkungen haben kann, die aber meisten erst nach Programmstart entdeckt werden.
stacks_image_6ABCE32F-D0DF-4CD8-97A4-D89137D689C9
Als nächstes müssen die Binding-Eigenschaften des NSObjectController eingestellt werden. Um genau zu sein, die Eigenschaften für den Controller Content, also den Inhalt. Die Verbindung soll zu der Instanz MyController und dort zur Eigenschaft rpgCharacter gemacht werden, wie die folgende Abbildung zeigt. Auch hier ist wieder Key-Value-Coding im Einsatz, denn die zu verbindenden Daten werden im Model Key Path im Inspector als Zeichenkette angegeben.
stacks_image_BB4F3A06-C289-4119-AB49-D96837DEF1DC
Jetzt ist der Controller an das Objekt rpgCharacter gebunden. Die einzelnen Textfelder nun mit dem Controller zu verbinden funktioniert auch wieder mit dem Interface Builder.

Markieren Sie das oberste der Label auf der rechten Seite und öffnen Sie im Inspector die Binding-Eigenschaften für dieses Steuerelement. Es sind die Werte, also Value, die verbunden werden müssen. Aktivieren Sie die Bind To Checkbox und wählen Sie den Character Controller in der nebenstehenden Combobox. Das konkrete Feld können sie in der Combobox Model Key Path auswählen. Wenn Sie im Controller alle Keys eingegeben haben, werden diese jetzt hier angezeigt. Haben Sie diesen Schritt übersprungen, können Sie aber auch direkt den Namen der Instanzvariablen eintragen und es wird trotzdem funktionieren. Wiederholen Sie diesen Schritt für alle Label, dem Textfeld werden wir uns gesondert auf der nächsten Seite annehmen.
stacks_image_31C3465F-141A-4568-83CE-23728B36AB38
Es ist wichtig, dass Sie wirklich an Value binden, denn dies ist der Wert, der dann im Label angezeigt werden wird. Es gibt durchaus noch weitere Möglichkeiten für Binding, zum Beispiel an die Schriftart oder Textfarbe.
stacks_image_BFE3E678-06BC-4CA1-B349-ACDF5D5CCF1A