Multi-View Architektur - ein Delegate?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Multi-View Architektur - ein Delegate?

    Hallo Community,
    in meiner Cocoa-Anwendung verwende ich 3 xib-Dateien mit den zugehörigen View-Controllern. Zum einen den mainView und zwei subviews die in einer NSBox im mainView dargestellt werden.
    Nun möchte ich mit den Steuerelementen in den Subviews auf die Methoden des App Delegates zugreifen. Wie mache ich das - und ist das überhaupt legitim? Wenn nicht: Wie werden die Usereingaben in einem Subview normalerweise gehandelt ? Werden sie an den App Controller geschickt? Gibt es dazu eine Dokumentation ? Habe leider in der Dokumentation nichts dazu gefunden, falls jemand einen Link hat wäre das natürlich auch toll :)

    chuck

    EDIT: sorry, falsches Unterforum
  • Thallius schrieb:

    MVC

    Gruß

    Claus

    Gut danke. Ich denke dass ich das MVC-Prinzip grundlegend verstanden habe. Ich habe nun 3 verschiedene Views mit ihren zugehörigen Controllern.
    Nun will ich zwischen den Views interagieren. Das ganze erfordert ja eine Art "Main Controller" was in meinen Augen der App Delegate ist. Meine Frage ist also, ob das die richtige Antwort ist und wenn ja wie man das prinzipiell umsetzt.
  • nein Du hast es nicht verstanden weil dann würde sich Dir die Frage gar nicht stellen ;)

    Wenn Du 1 Model hast dann können alle Controller auf dieses 1 Model zugreifen und damit brauchst du keine Umwege über irgendwelche Delegates

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    nein Du hast es nicht verstanden weil dann würde sich Dir die Frage gar nicht stellen ;)
    Wenn Du 1 Model hast dann können alle Controller auf dieses 1 Model zugreifen und damit brauchst du keine Umwege über irgendwelche Delegates.

    Und wie können diese drei unterschiedlichen Controller deiner Meinung nach auf dieses eine Modell zugreifen?
    Dieses eine Modell, nennen wir es 'NSArray', existiert ja zunächst nur in dem Controller, in dem es erstellt wurde.
    Persistieren und in jedem Controller neu laden? :P

    Eigentlich hast du nur zwei Möglichkeiten. Wenn du Core Data nutzt hast du uneigentlich sogar noch eine Dritte, ich persönlich verabscheue NSFetchedResults beziehungsweise den inflationären Umgang damit, weshalb ich sie nicht weiter erwähnen werde.
    • Du greifst auf die Werte in deinem Delegate direkt zu
    • du schleifst eine Referenz auf das Modell in den ViewControllern mit


    Ich bevorzuge ja eine Mixtur aus Beidem: der Controller bekommt Getter und Setter für eine gefakte Property. Diese Getter und Setter greifen dann auf die jeweiligen Getter und Setter des Delegates zu.
    Dadurch wird der Zugriff insoweit gekapselt, als dass du nur deinen Getter und Setter auf Änderungen im Modell anpassen musst und nicht die gesamte Klasse.

    Faktisch sieht es allerdings nach einem Design-Fehler aus, wenn du in 3 unterschiedlichen Views ein und denselben Aspekt deines Modells anpassen möchtest. ;)
    Sagen wir, dein Modell beinhaltet Kundendaten. Im ersten View selektierst du einen Kunden.
    Direkt danach kann dein Delegate den Controllern für die BoxViews einfach den selektierten Kunden übergeben. Vielleicht sogar dem ersten 'kunde.adresse' und dem zweiten 'kunde.kontakt'.
    So greifen die Controller dann auf ihre Instanzvariable zu und sind von deinem MainController komplett losgelöst.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • chukky94 schrieb:

    Nun möchte ich mit den Steuerelementen in den Subviews auf die Methoden des App Delegates zugreifen. Wie mache ich das - und ist das überhaupt legitim?

    Nein, ist es nicht. Im MVC-Muster sollten die Views niemals direkt auf den Controller zugreifen, sondern die Controller-Schicht nur über Änderungen benachrichtigen. Dazu gibt es mehrere Möglichkeiten; z. B. Target-Action, die Controller observieren Eigenschaften des Views, der View unterstützt ein eigenes Delegate oder eine Datenquelle. Dabei ist wichtig, dass die Viewklassen die Controllerklassen nicht kennen, also nicht abhängig von diesen sind.
    „Meine Komplikation hatte eine Komplikation.“
  • Lucas de Vil schrieb:

    Thallius schrieb:

    nein Du hast es nicht verstanden weil dann würde sich Dir die Frage gar nicht stellen ;)
    Wenn Du 1 Model hast dann können alle Controller auf dieses 1 Model zugreifen und damit brauchst du keine Umwege über irgendwelche Delegates.

    Und wie können diese drei unterschiedlichen Controller deiner Meinung nach auf dieses eine Modell zugreifen?
    Dieses eine Modell, nennen wir es 'NSArray', existiert ja zunächst nur in dem Controller, in dem es erstellt wurde.


    Naja, normalerweise werden die Daten eines Models janicht fest codiert sondern aus einer DB, Coredata oder einer XML oder was auch immer gelesen. Ich kann also beliebig viele Controller auf diese Daten zugreifen lassen, wenn ich denn diese miteinandern synce. Bei Coredata läuft das z.B. über den Merge. Ich kann dort einfach 3 Controller mit dem gleichen Model laufen lassen und muss nur bei einer Änderung alle Instanzen mergen. Das kann man bei SQlite oder XML natuerlich genauso implementieren. Ich brauche also weder FetchRequests noch irgendwelche durchgeschliffenen Properties.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Lucas de Vil schrieb:

    Faktisch sieht es allerdings nach einem Design-Fehler aus, wenn du in 3 unterschiedlichen Views ein und denselben Aspekt deines Modells anpassen möchtest. ;)
    Sagen wir, dein Modell beinhaltet Kundendaten. Im ersten View selektierst du einen Kunden.
    Direkt danach kann dein Delegate den Controllern für die BoxViews einfach den selektierten Kunden übergeben. Vielleicht sogar dem ersten 'kunde.adresse' und dem zweiten 'kunde.kontakt'.
    So greifen die Controller dann auf ihre Instanzvariable zu und sind von deinem MainController komplett losgelöst.
    Also prinzipiell ist mein Problem relativ simpel und so wie du es beschreibst. Ich arbeite NICHT mit Core Data und habe somit keinen zusammengefassten ManagedObjectContext, der mir aber auch nur bedingt helfen würde. Die Methode die den contentView der Box steuert liegt nunmal im Hauptdelegate. nun möchte ich diese von einem Subview mit einer IBAction aufrufen und sagen wir ein Objekt aus dem Model übergeben. Was wäre der sauberste weg das zu tun ? Ein direkter Zugriff auf

    Quellcode

    1. [[NSApplication sharedApplication] delegate]
    ?



    chuck
  • chukky94 schrieb:

    Die Methode die den contentView der Box steuert liegt nunmal im Hauptdelegate


    Und da liegt der Fehler. Das hat da nichts verloren. Erstelle dafür einen DatenController und meinetwegen intialisiere diesen im appdelegate wenn es denn gar nicht anders geht, aber dann gebe den Controller an den ViewController weiter und benutze diesen.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Methoden? Die Methoden baust du schön in deinen zum jeweiligen View gehörenden Controller ein. Da wird nirgendwo anders weitergeleitet.
    (Jaaa, ResponderChain. Das ist aber eher was für Band 2 :P)

    Also:
    Die Methode die den contentView der Box steuert kommt in den Controller der Box. Jede.
    Und greift auf die Property des Controllers zu, welche das Objekt repräsentiert, welches die Box darstellen soll.

    Dein Hauptdelegate setzt dann einfach nur die Property des Controllers.
    (Und dein Controller informiert dann sein View, welche Inhalte sich da geändert haben.)

    Dein Controller ist nur für sein View zuständig und so unabhängig von allen anderen Controllern, wie es nur eben geht.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • macmoonshine schrieb:

    chukky94 schrieb:

    Nun möchte ich mit den Steuerelementen in den Subviews auf die Methoden des App Delegates zugreifen. Wie mache ich das - und ist das überhaupt legitim?

    Nein, ist es nicht. Im MVC-Muster sollten die Views niemals direkt auf den Controller zugreifen, sondern die Controller-Schicht nur über Änderungen benachrichtigen. Dazu gibt es mehrere Möglichkeiten; z. B. Target-Action, die Controller observieren Eigenschaften des Views, der View unterstützt ein eigenes Delegate oder eine Datenquelle. Dabei ist wichtig, dass die Viewklassen die Controllerklassen nicht kennen, also nicht abhängig von diesen sind.

    Im MVC-Modell können sehr wohl Views auf Controller zugreifen. In Objective-C kann man das nur abstrakt halten.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Thallius schrieb:

    Lucas de Vil schrieb:

    Thallius schrieb:

    nein Du hast es nicht verstanden weil dann würde sich Dir die Frage gar nicht stellen ;)
    Wenn Du 1 Model hast dann können alle Controller auf dieses 1 Model zugreifen und damit brauchst du keine Umwege über irgendwelche Delegates.

    Und wie können diese drei unterschiedlichen Controller deiner Meinung nach auf dieses eine Modell zugreifen?
    Dieses eine Modell, nennen wir es 'NSArray', existiert ja zunächst nur in dem Controller, in dem es erstellt wurde.


    Naja, normalerweise werden die Daten eines Models janicht fest codiert sondern aus einer DB, Coredata oder einer XML oder was auch immer gelesen. Ich kann also beliebig viele Controller auf diese Daten zugreifen lassen, wenn ich denn diese miteinandern synce. Bei Coredata läuft das z.B. über den Merge. Ich kann dort einfach 3 Controller mit dem gleichen Model laufen lassen und muss nur bei einer Änderung alle Instanzen mergen. Das kann man bei SQlite oder XML natuerlich genauso implementieren. Ich brauche also weder FetchRequests noch irgendwelche durchgeschliffenen Properties.

    Gruß

    Claus

    Und woher wissen deine Controller, auf welche DB, welches XML oder welchen Kontext sie zugreifen sollen?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Lucas de Vil schrieb:

    Methoden? Die Methoden baust du schön in deinen zum jeweiligen View gehörenden Controller ein. Da wird nirgendwo anders weitergeleitet.
    (Jaaa, ResponderChain. Das ist aber eher was für Band 2 :P)

    Also:
    Die Methode die den contentView der Box steuert kommt in den Controller der Box. Jede.
    Und greift auf die Property des Controllers zu, welche das Objekt repräsentiert, welches die Box darstellen soll.

    Dein Hauptdelegate setzt dann einfach nur die Property des Controllers.
    (Und dein Controller informiert dann sein View, welche Inhalte sich da geändert haben.)

    Dein Controller ist nur für sein View zuständig und so unabhängig von allen anderen Controllern, wie es nur eben geht.
    Also heist das konkret, dass ich für meine 3 .xib-Dateien MainMenu.xib , viewOne.xib, viewTwo.xib jeweils einen Controller habe der auch die IBActions empfängt ?
    Diese Controller würden dann im Delegate instanziiert, der auch als Observer für die Controller dient, sofern "controller-übergreifende" Maßnahmen notwendig sind?
    Bisher habe ich die IBActions des MainWindows immer direkt an den Delegate geschickt. Brauche ich hier einen neuen Controller?
  • macmoonshine schrieb:

    Amin Negm-Awad schrieb:

    Im MVC-Modell können sehr wohl Views auf Controller zugreifen. In Objective-C kann man das nur abstrakt halten.

    Ich korrigiere mich: Im MVC-Muster unter Cocoa / Cocoa Touch sollten die Views niemals direkt auf den Controller zugreifen, ...

    Das meinte ich nicht.

    Action-Target ist ein Zugriff des Views auf den Controller. Er ist nur abstrakt.
    Bindings sind ein Zugriff des Views auf den Controller. Er ist nur abstrakt.

    Views kommunizieren ausschließlich mit dem Controller. In jeder Ausprägung von MVC. In Objective-C lässt sich das nur abstrakt formulieren.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?