2009-06-20 6 views
3

Als Neuling in Cocoa habe ich Schwierigkeiten zu verstehen, warum die generischen NSResponder-Unterklassen Schlüsselereignisse so implementieren, wie sie es zu tun scheinen.Warum behandelt eine NSWindow- oder NSView-Instanz ihre eigenen Schlüsselereignisse und nicht ihren Delegaten?

In meinem Programm habe ich eine NSWindow-Unterklasse, die den gesamten Bildschirm einnimmt und unbedingt Schlüsselereignisse behandeln muss. Es gibt mehrere Hauptbefehle, die den gesamten Status des Programms ändern können (z. B. einen Zeitgeber pausieren, wenn der Benutzer die Leertaste drückt), wobei es nicht sinnvoll ist, Teilansichten wie ein NSTextField-Handle zu haben.

Es scheint mir, dass der Delegat (Controller) diese Ereignisse erhalten soll. Stattdessen muss ich entweder einen Haufen unordentlichen Klebstoffcode schreiben, damit das Fenster (über seine keyDown: und interpretKeyEvents: Selektoren) den Controller benachrichtigt, oder ich muss einfach eine Menge Controller-Code in die NSWindow-Unterklasse selbst verschieben.

Das ist chaotisch und mein Bauchgefühl sagt mir, dass ich etwas vermisse. Gibt es eine sauberere Lösung?

Antwort

4

Wenn Sie es richtig eingerichtet haben, wird der Delegat NSWindow die Nachrichten empfangen. Cocoa verwendet die Responder-Kette, um Nachrichten vom ersten Responder weiterzuleiten - die Schlüsselansicht für Schlüsselnachrichten und die Ansicht, auf die/etc/angeklickt wurde. für Maus-Nachrichten - zurück durch die Superviews, durch das Fenster und schließlich zum Vertreter des Fensters. Es gibt ein ziemlich gutes Diagramm der typischen Antwortkette auf Apple's site.

Sie sollten nie NSWindow von der Unterklasse ableiten, es sei denn, Sie implementieren einige ausgefallene Fensterzeichnung oder etwas anderes in diesen Zeilen. Cocoa bietet die Klasse NSWindowController, um sich als Controller für ein Fenster und dessen Inhalt zu verhalten.

Das übliche Muster ist die Unterklasse NSWindowController und fügen Sie Ihre IBOutlet s hinzu, und verwenden Sie dann eine NIB, um Ihren Fensterinhalt auszulegen. Sie machen Ihre NSWindowController Unterklasse die Klasse des Dateieigentümer-Proxy in Interface Builder. Und Sie weisen dem Fenster-Controller auch die delegate des Fensters zu, so dass er Teil der Responder-Kette werden kann. Um schließlich Fenster zu erstellen, verwenden Sie NSWindowController 's Methode, die das Laden der NIB mit einem neuen Fenstercontroller als Besitzer der Datei automatisiert.

Ich würde empfehlen auf Fenster-Controller in der Cocoa-Dokumentation zu lesen, weil sie den fehlenden Link bieten, den Sie suchen.

+0

Mein Delegat ist eigentlich eine NSWindowController-Unterklasse. Ich benutze den Interface Builder nicht, weil ich versuche, ein Fenster zu erstellen, das zum Zeitpunkt der Instanziierung grenzenlos sein kann, und IB scheint das nicht zuzulassen - außerdem versuche ich, die Details zu lernen und IB verbirgt sich sehr, also dachte ich mir, für diese App wäre es wert, "auf die harte Tour" zu lernen. Vielen Dank für den Link zu diesem Abschnitt der Dokumentation. Ich habe es gelesen, aber die Details über den NSWindowController als letzten Ausweg verpasst. Offensichtlich habe ich einen Fehler bei der Verwaltung der Responder-Kette gemacht. – EricB

Verwandte Themen