Kommunikation zwischen Klassen

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

  • Kommunikation zwischen Klassen

    Hallo!

    Habe jetzt endlich Zeit mich richtig mit Objective-C und iPhone SDK zu beschäftigen.
    Allerdings stehe ich mit der objektorientierten Programmierung ein wenig auf Kriegsfuss!
    Habe es heute geschafft einen HelloWorld-String mittels Klick auf einen Button in einem Textfeld darzustellen. Dazu habe ich einfach eine Action + ein Outlet mit entsprechender Methode in der ViewController-Klasse implementiert.

    Jetzt möchte ich einen String der in einer anderen Klasse generiert wird in diesem Textfeld ausgeben - jedoch weiss ich nicht ganz wie ich das angehen soll! Bzw. wie ich die entsprechenden Klassen "zusammenbringe".

    Wäre für Eure Hilfe sehr dankbar!
  • RE: Kommunikation zwischen Klassen

    Du brauchst eine Verbindung zum Textfeld. Dies bewerkstelligst du mit einem Outlet.

    Dann benötigst du irgendeine Verbindung zu dem Erzeuger-Objekt. Vllt.kannst du das auch imNib instantieren und ein Outlet benutzen. Vllt willst du es in deiner Controllerklasse instantieren und mit einemSetter "merken". Dazumüsste man mehr wissen.
    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"?
  • OK, hab mir nochmal das Model-View-Controller design pattern reingezogen.
    Und zwar hab ich das so verstanden:
    View - ist die GUI, also alles theoretisch alle Objekte die im .xib-File definiert sind.
    Controller - beinhaltet die Outlets + Actions um auf Ereignisse der GUI zu reagieren.
    Model - beinhaltet den eigentlichen Code

    Mein Problem ist, dass alle Beispiele aus den Büchern bzw. aus dem Internet entweder zu einfach oder zu schwierig sind.
    Z.B. ist mir so ein Instrumentenbeispiel wo ich eine Instrumentenklasse habe und eine Gitarre und ein Piano ableite völlig klar. Hier erzeug ich in der Main (ich nehme an die gehört bezüglich MVC zum Model?!) die ganzen Objekte und der Zugriff auf die Methoden passiert über die Instanzvariablen.
    Wenn ich jetzt aber z.B. in der Main ein Objekt erzeuge, was habe ich dann für Möglichkeiten - von anderen Klassen aus - auf die Methoden dieses Objektes zuzugreiffen? Das geht ja eben nur über die Instanzvariable in der Klasse (also Main) in der das Objekt erzeugt wurde?!

    Konkret:
    Ich habe das Ganze mit einer fertigen Klasse, welche die aktuellen geografischen Daten des Benutzers ermittelt, probiert - ein Objekt dieser Klasse wird in der Main erzeugt. Ebenfalls habe ich eine GUI mit Textfeld (für die Ausgabe) und einem Button. Entsprechende Actions und Outlets sind in der Controllerklasse. Wenn ich jetzt auf den Button drücke wird die entsprechende Methode in der Controllerklasse aufgerufen. Mittels dieser Methode würde ich nun gerne eine Funktion "getLocationData" aufrufen, was aber aufgrund der Objekterzeugung in der Main auch nur von dieser aus geht.
    Genau hier steh ich an - ich habe wohl was Grundlegendes nicht verstanden?!

    Auf jeden Fall danke ich Euch für Eure Unterstützung!
  • Model: Das sind vor allem die Daten. Den meisten Code hast du im Controller, nicht im Model.

    In Main kannst du nur darauf zugreifen, wenn du eine Variable hast. Das muss nicht eine Instanzvariable sein (Main ist auch keine Klasse, das sei hier aber mal gleichgültig.) Wenn du etwas weiter gehst, dann siehst du im Abschnitt Speicherverwaltung das Beispiel mit Firma und Person. Hier siehst du, dass eine Gruppe Instanzvariablen hat, die auf die Person verweisen. Lies dir das vllt noch einmal durch.

    Okay, dein Problem ist, dass die Beispiele zur Speicherverwaltung einfach nicht für GUI gedacht sind. Du musst da noch weiterlesen. Dein Problem dürfte sich allerdings durch etwas komplizierteres lösen, nämlich einen Singleton. Die einfachste Art ist es, einen solchen in MainMenu.nib (jetzt: xib) zu erzeugen. Das kommt aber erst ne ganze Weile später.

    Auf welcher Seite bist du?

    Amin Negm-Awad

    PS.: Vielleicht hilft dir das als Einstieg:
    cocoading.de/Common/Article.php?Area=2&Article=3
    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"?
  • Danke erstmal!
    Das Speicherverwaltungskapitel hatte ich schon durch - das ist allerdings schon 7 Wochen her.
    Hatte dazwischen keine Zeit wegen Semesterschluss. Dafür hab ich jetzt umso mehr Zeit. Habe gerade nochmal mit dem Kapitel begonnen - hoffe ich bring die nächste Zeit was weiter.
    Gibt es eigentlich sowas wie Legasthenie bezüglich objektorientierter Sprachen :)
    Ich hatte bei C, soweit ich mich erinnern kann, nie solche Verständnissprobleme.
  • Ja, das ist weit verbreitet und liegt einfach an der zunächst erfolgten anderen Sozialisierung durch eine einfach prozedurale Sprache.

    Ich fange in der nächsten Auflage wirklich damit an: "Was passiert eigentlich, wenn der Benutzer auf einen Button klickt?". Also nichts mit main() oder so.
    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"?
  • Da möchte ich mich auch mal mit anhängen. Ich stehe vor dem gleichen Problem:

    Ich erzeuge in einer TeblView eine View und möchte den Text, den man in der View eingibt, in meiner TableView benutzen. Ich habe keine Idee wie? Habt ihr vielleicht einen kleinen Tip? Aus den Posts in diesem Thread bin ich nicht schlau geworden :(

    So erzeuge ich die View in der TableView:

    Quellcode

    1. - (IBAction)addAction:(id)sender{
    2. if (ncvController == nil)
    3. {
    4. self.ncvController = [[NewCourseViewController alloc]
    5. initWithNibName:@"NewCourseViewController" bundle:nil];
    6. }
    7. [[self navigationController] pushViewController:ncvController animated:YES];
    8. }


    Habe an ein Austausch Objekt gedacht, so würde ich es in c# machen. Die neue View Modal aufrufen und als ModelResult das Autauschobjekt zurück geben. Aber ich weiß nicht wie und ob ich das in ObjC auch so machen kann/soll?

    Vielen Dank

    dragi
  • Es scheint als wäre ich nicht allein mit meinem Problem ;)
    Ich tu mich gerade auch ziemlich schwer folgendes umzusetzen:
    Eine MainView.xib hat ein Label und setzt beim initWithNibName im passenden MainViewController einen Text. Jetzt möchte ich aber nicht nur durch eine Schaltfläche auf der View das Label manipulieren, sondern auch aus einer anderen Klasse heraus, weil da andere Dinge abgearbeitet werden, die aber im Ergebnis den Text des bestimmten Labels beeinflussen.
    Die Crux für mich ist nun: Wie bekomme ich in der anderen Klasse die aktuelle Instanz des MainViewController Objektes, um da den ActionHandler zu feuern? Eine neue Instanz des ViewController zu erzeugen hilft ja hier nicht, weil es nichts auf der aktuellen View anzeigt.
    Ich bin wirklich ratlos an dieser Stelle. Leider sind meine ObjC Kenntnisse erst ca. 2 Wochen alt und mit meinen Uni-Java Kenntnissen komme ich hier auch nicht weiter ;)
    Da gibt es doch bestimmt eine simple Lösung für?

    MainViewController:

    Quellcode

    1. -(IBAction *)someMethod:(id)sender{
    2. label.text = @"lalala";
    3. }


    SomeObject:

    Quellcode

    1. -(void)showSomeText{
    2. // MainViewController *mVC = [MainViewController alloc]init;
    3. // mVC someMethod;
    4. }
  • Original von GMan
    Es scheint als wäre ich nicht allein mit meinem Problem ;)
    Ich tu mich gerade auch ziemlich schwer folgendes umzusetzen:
    Eine MainView.xib hat ein Label und setzt beim initWithNibName im passenden MainViewController einen Text. Jetzt möchte ich aber nicht nur durch eine Schaltfläche auf der View das Label manipulieren, sondern auch aus einer anderen Klasse heraus, weil da andere Dinge abgearbeitet werden, die aber im Ergebnis den Text des bestimmten Labels beeinflussen.


    Also irgendwie finde ich dies schrullig.
    Die Klasse hat doch normalerweise überhaupt nix mit deiner Schaltfläche am Hut.

    Idee:
    Umdenken.

    Du kannst natürlich einer Methode deiner Klasse nen Zeiger auf das zu manipulierende Objekt mitgeben.

    Quellcode

    1. -(void)machWasUndAendereTextVon:(id)irgendwas {
    2. //Schaffe, schaffe, Haeusle baue
    3. [irgendwas setTitle:@"Titel"];
    4. }

    Problem: übergibst du ein Objekt, das keinen Titel hat, dann wird das Ganze nichts.

    Dein Controller (und nur der) sollte den Text deines Buttons ändern.
    Ob der das jetzt in der Buttonklick-Methode macht oder sonstwann ist ja erst mal egal.
    Du kannst beispielsweise deine Methode abändern.

    Quellcode

    1. -(NSString*)machWas {
    2. //Schaffe, schaffe, Haeusle baue
    3. return @"Titel";
    4. }


    Im Controller tippst du dann [label setTitle:[instanzobjekt machWas]]; und fertig.

    Aber immer, wenn ich sowas machen will, stellt sich später heraus dass ein Denkfehler drin steckt und es eigentlich Blödsinn ist.

    Warum soll dein Klassenobjekt das Buttonlabel ändern?
    Auf was soll es das ändern?
    «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
  • schrullig? :D

    Ok...vielleicht muss ich weiter ausholen (ums noch schlimmer zu machen ;)):
    Mein MainViewController hat eine Methode, die ein Label und ein ImageView so setzen kann, dass ein roter oder grüner Kringel angezeigt wird und "OFFLINE" oder "ONLINE" in der View steht.
    Der Ordnung halber habe ich nun eine seperate Klasse, die für mich einen Login-Vorgang ausführt und einen Cookie analysiert, der entweder aussagt: "Hey, du bist eingeloggt" oder "Nö, alles Mist...".
    Jetzt möchte ich mit diesem Wissen das Label und die ImageView des MainViewControllers so manipulieren, dass da der korrekte Status angezeigt wird. Dazu würde ich nun gerne die og. Methode aufrufen.
  • Wenn ich das richtig verstanden habe hilft dir vielleicht dieses Pseudogecode:
    Login-Klasse

    Quellcode

    1. // Deine Variablendefinitionen
    2. bool _isLoggedIn;
    3. // Dein Klassenkram
    4. - (void)setIsLoggedIn:(bool)status {
    5. _isLoggedIn = status;
    6. }
    7. - (BOOL)isLoggedIn {
    8. return _isLoggedIn;
    9. }
    10. - (void)logInUserWithName:(NSString*)name andPassword:(NSString*)pass {
    11. //Dein Login-Zeugs
    12. [self setIsLoggedIn:YES];
    13. }
    14. - (void)logOutCurrentUser {
    15. //Dein Logout-Zeugs
    16. [self setIsLoggedIn:NO];
    17. }
    18. // Noch mehr Klassenkram, idealerweise nur Dealloc
    Alles anzeigen


    AppDelegate

    Quellcode

    1. //Das Uebliche
    2. if ([LoginObjekt isLoggedIn] ) {
    3. [image setImage:loggedIn];
    4. [label setTitle:@"User logged in"];
    5. [button setTitle:@"Logout"];
    6. } else {
    7. [image setImage:loggedOut];
    8. [label setTitle:@"User logged out"];
    9. [button setTitle:@"Login"];
    10. }
    11. //Mehr vom Ueblichen
    Alles anzeigen


    Also vom Prinzip her:

    Deine Klasse weiß, wie ihr Status ist.
    (Eingeloggt, Ausgeloggt, Login-Fehler...)
    Sie weiß nicht, wen das interessiert.
    (Modell)

    Dein Label zeigt etwas an.
    Es weiß nicht, wer ihm das sagt.
    (View)

    Dein Controller muss die Information deiner Klasse an das Label weitergeben.

    So würde ich das halt machen, denn MVC ist mein Freund.
    «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
  • Schau Dir mal das Thema "Bindings" in der Apple Doku an.
    Sehr kurz gesagt geht's bei "Bindings" darum, dass Du den Controller-Kram, der die GUI aktualisiert, nicht mehr brauchst. Mit Bindings änderst Du Dein DATEN-Modell im Code und in der GUI erfolgt die Anpassung an die Änderung automatisch - eben durch "Bindings".

    Steht - sehr gut beschrieben - "im Buch".

    No.
  • Original von GMan
    Die ganze ObjC Welt ist noch sehr neu für mich (ca. 2 Wochen Erfahrung) und ich hatte nicht vor "schrullig" oder nervend zu wirken.


    Ich fand nur den Ansatz schrullig im Sinne von unüblich.
    Dass Obj-C ein paar Hirnwindungen in der Anfangszeit verdreht ist normal.
    Ich probiere seit fast 2 Jahren mal was Sinnvolles auf die Beine zu bekommen und häng immer wieder an fehlerhaften Designs fest.
    Aber nur so lernt man. :D

    (Um Bindings kümmere ich mich später, die sind mir noch zu suspekt.)
    «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
  • Doch.
    Ich muss das Modell so gestalten, dass sie funktionieren.
    Und momentan bin ich mit KVC noch voll überfordert.

    Ich lerne halt langsam. ;)
    «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
  • OK, jetzt habe ich aber nochmal eine Frage!

    Also, 2 Views und ein Conroller können das problem lösen, das leuchtet ein. Aber jetzt folgendes: Ich habe die eine xib datei im Interface Builder geöffnet und deren Files Owner ist ihr Controller. Wie bekomme ich da nun die zweite View hinzugefügt um die auch mit dem Files Owner zu verbinden?

    Danke für eure Hilfe

    dragi
  • Wahrscheinlich versteh ich dich nicht so ganz, aber ich würde eine View aus der Toolbox hineinziehen und die im Controller mit einem IBOutlet versehen und als Subview definieren. Danach könntest du sie mit einer Methode <f***nda.com> in den Vordergrund bringen.

    Übrigens:
    Nochmal danke für eure Hilfe gestern: Habs jetzt mit einer Mischung aus beidem gelöst. Der Login setzt ein "isOnline" auf YES und das wird vom ViewController per key Observer beobachet und dementsprechend der Status verändert. *perfekt*