Benötige Hilfe bei Klassenerstellung

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

  • Benötige Hilfe bei Klassenerstellung

    Hallo,
    ich bringe mir an Programmierung alles selber bei, allerdings hapert es manchmal. Genau wie jetzt.
    Ich schildere euch kurz den Sachverhalt. Es geht nur ums lernen, die folgende Anwendung erfüllt keinen Sinn.

    Ich möchte eine Anwendung für das iPhone schreiben, welche in einem TableView Vor- und Nachnamen von Personen anzeigt. Oben befindet sich ein Plus-Button um eine weitere Person hinzuzufügen.
    Wenn der Benutzer auf den Plus-Button klickt, dann soll ein neuer View aufgehen mit 2 Textfelder und einem Button. Der Benutzer soll in die Textfelder jeweils den Vor- und den Nachnamen eingeben. Sobald der Benutzer dann auf den Button klickt, wird ein neues Objekt der Klasse "Person" mit eingegebnen Vor- und Nachnamen erzeugt. Dazu mein Code:

    #import <Foundation/Foundation.h>

    @interface Person : NSObject

    @property (nonatomic, strong) NSString* vorname;
    @property (nonatomic, strong) NSString* nachname;
    - (void) setVorname: (NSString *) vn;
    - (void) setNachname: (NSString *) nn;

    @end


    #import "Person.h"

    @implementation Device

    - (void) setVorame: (NSString *) vn
    {
    _vorname = vn;
    }

    - (void) setNachname: (NSString *) nn
    {
    _nachname = nn;
    }

    @end



    So, nun würde ich auf folgende Weise eine Person hinzufügen:

    Person *person1 = [[Person alloc] init];

    person1.vorname = vornameTextfield.text;

    person1.nachname = nachnameTextfield.text;



    Jetzt zu meinem Problem:
    Wie kann ich realisieren, dass bei jedem hinzufügen automatisch ein neues Objekt erzeugt wird? (Siehe fett, unterstrichen und rot). In diesem Fall würde ich ja stets das eine Objekt überschreiben?

    Im weiteren würde ich dann alle erstellten Objekt in ein dynamisches Array speichern und per TableView auflisten lassen.

    Vielen Dank für eure Unterstützung.
  • Hallo,
    danke für die schnelle Antwort.

    Angenommen ich habe jetzt hier die IBAction wenn der Button zum erstellen genutzt wird:

    - (IBAction)createPerson:(id)sender
    {
    .....
    }

    Was muss ich dann da rein tippen, damit ein dynamisches Objekt erstellt wird?
    In de Moment in dem Button geklickt wird. Soll der "Constructor" (oder wie man es nennt) ein neues Objekt anlegen und Vor- und Nachnamen setzten.
    Wie würde die Methode aussehen?
  • In Objective-C und Swift heißt das Initializer. :)

    Eigentlich hast du eh schon den richtigen Code geschrieben:

    Quellcode

    1. - (IBAction)createPerson:(id)sender
    2. {
    3. Person *person = [[Person alloc] init];
    4. person.vorname = vornameTextfield.text;
    5. person.nachname = nachnameTextfield.text;
    6. }

    Hier wird bei jedem Aufruf der Methode -createPerson: ein Objekt 'person' erstellt. Aber da du nichts damit machst, wird es am Ende der Methode gleich wieder gelöscht.
  • Du musst dieses Objekt in einen NSMutableArray einfügen, um es in weiterer Folge verwenden zu können.

    Quellcode

    1. [mutableArrayInstance addObject: person];

    'person' ist nur der Name des Pointers in dieser Methode. Wenn du die Objekte aus dem Array abrufst, kannst du den Pointer wieder anders benennen, jedoch darf der gleiche Name nicht mehrmals in einer Methode vorkommen.
  • Nils Loh schrieb:

    Ich möchte die Objekte ja aber gerne weiter verwenden. Denn diese sollen dann an Array weitergegeben werden und im TableView gezeigt werden.
    Dadruch brauche ich ja mehrere Objekte, aber die können ja nicht alle Person heißen, oder?

    Liebe Grüße


    Doch klar! Du erstellst ja vermutlich bei jedem Button-Klick eine neue Person. Dann kann sie auch so heißen.
  • TheFuriousLion schrieb:

    In Objective-C und Swift heißt das Initializer. :)

    Eigentlich hast du eh schon den richtigen Code geschrieben:

    Quellcode

    1. - (IBAction)createPerson:(id)sender
    2. {
    3. Person *person = [[Person alloc] init];
    4. person.vorname = vornameTextfield.text;
    5. person.nachname = nachnameTextfield.text;
    6. }

    Hier wird bei jedem Aufruf der Methode -createPerson: ein Objekt 'person' erstellt. Aber da du nichts damit machst, wird es am Ende der Methode gleich wieder gelöscht.



    Das heißt ich nehme diesen Text als Methode auf?
    Aber wie heißen denn dann die Objekte wenn ich diese weiter verwenden möchte?

    Vielleicht möchte ich anderer Stelle ja die Namen zweier verschiedener Person ausgeben.
    Dann würde ich bspw. wie folgt schreiben:

    Quellcode

    1. textfeld1.text=person1.name;
    2. textfeld2.text=person2.name;

    Aber meine Objekte heißen ja nicht person1 und person2, sondern alle person?
  • Nils Loh schrieb:

    Das heißt ich nehme diesen Text als Methode auf?
    Nein, -createPerson:, +alloc und -init sind Methoden. person, textfeld1 und textfeld2 sind Objekte. Objekte haben Eigenschaften, sogenannte Properties, wie text, textColor, etc. Nähere Informationen findest du in Apples Class Reference.

    Wenn du Objekte in einem Array speicherst, kannst du sie auch wieder herausholen.

    Quellcode

    1. [someArray objectAtIndex: index]
    Wenn du beispielsweise die 1. Person im Array willst, ist index 0, willst du die 2. Person, ist index 1, usw.
  • Das kommt ganz auf den Anwendungsfall an.
    TableView sähe beispielsweise so aus:

    Quellcode

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3. UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    4. Person * person = (Person *)[self personMutableArray][[indexPath row]];
    5. [[cell textLabel] setText:[NSString stringWithFormat:@"%@ %@", [person firstName], [person lastName]]];
    6. return cell;
    7. }
    Alles anzeigen
  • Ich habe eine Anwendung im AppStore gefunden, welche meine Problematik vielleicht besser erklärt.
    Schaut euch mal die App RWE Stromrechner an.
    Das ist quasi genau mein Anwendungsfall.

    Dort kann man ein Gerät im separaten View hinzufügen und dieses quasi dann im Table View ansehen.

    Ich denke mir, dass das genau so abläuft wie bei mir. Dort wird von jedem Gerät ein Objekt erstellt.

    Ist mein Ansatz denn da der richtige?
  • TheFuriousLion schrieb:


    Wenn du Objekte in einem Array speicherst, kannst du sie auch wieder herausholen.

    Quellcode

    1. [someArray objectAtIndex: index]
    Wenn du beispielsweise die 1. Person im Array willst, ist index 0, willst du die 2. Person, ist index 1, usw.


    Okay, das ist mir klar. Nur welche Methoden brauche ich denn dann alle?
    Ich habe ja nun setVorname, setName.

    Dann fehlen noch createPerson, alloc und init?
  • Wie die Methoden +alloc und -init implementiert sind weiß nur Apple. Für alle anderen sind sie einfach da zum Verwenden. +alloc und -init werden nur zur Objekterstellung benötigt, wie du es oben schon gemacht hast. +alloc sorgt für den Speicher des neu zu erstellenden Objekts, während -init eigentlich dazu gedacht ist, den Properties und Variablen Initialwerte zu setzen. Du kannst auch eigene Initializers schreiben, dazu lohnt sich ein Blick in Apples Dokumentation.
  • Ich glaube, Du hast zunächst ein gravierendes Verständnisproblem bei der Sichtbarkeit.

    Quellcode

    1. int dateiweit = 1;
    2. - void methode {
    3. int methodenweit = 2;
    4. do {
    5. int schleifenweit = 3;
    6. {
    7. int blockweit = 4;
    8. }
    9. {
    10. int blockweit = 5;
    11. {
    12. int subblockweit = 6;
    13. }
    14. {
    15. int subblockweit = 7;
    16. int subblockweit = 0; // Compilerfehler, da Variable schon deklariert.
    17. int blockweit = 0; // Compilerfehler, da Variable schon deklariert.
    18. int schleifenweit = 0; // Compilerfehler, da Variable schon deklariert.
    19. int methodenweit = 0; // Compilerfehler, da Variable schon deklariert.
    20. int dateiweit = 0; // Compilerfehler, da Variable schon deklariert.
    21. }
    22. int subblockweit = 9;
    23. int blockweit = 0; // Compilerfehler, da Variable schon deklariert.
    24. int schleifenweit = 0; // Compilerfehler, da Variable schon deklariert.
    25. int methodenweit = 0; // Compilerfehler, da Variable schon deklariert.
    26. int dateiweit = 0; // Compilerfehler, da Variable schon deklariert.
    27. }
    28. int subblockweit = 10;
    29. int blockweit = 11;
    30. int schleifenweit = 0; // Compilerfehler, da Variable schon deklariert.
    31. int methodenweit = 0; // Compilerfehler, da Variable schon deklariert.
    32. int dateiweit = 0; // Compilerfehler, da Variable schon deklariert.
    33. } while(false);
    34. int subblockweit = 12;
    35. int blockweit = 13;
    36. int schleifenweit = 14;
    37. int methodenweit = 0; // Compilerfehler, da Variable schon deklariert.
    38. int dateiweit = 0; // Compilerfehler, da Variable schon deklariert.
    39. }
    40. int subblockweit = 15;
    41. int blockweit = 16;
    42. int schleifenweit = 17;
    43. int methodenweit = 18;
    44. int dateiweit = 0; // Compilerfehler, da Variable schon deklariert.
    Alles anzeigen


    Das heißt in Deinem Fall, dass Deine Methode niemals die vorherige 'Person' Variable überschreibt. Am Ende der Funktion ist die Variable nicht mehr sichtbar. Du legst also immer wieder eine neue Variable an.

    Deine Grundbefürchtung ändert sich dadurch natürlich nicht. Ob Du jetzt eine Variable überschreibst oder sie nicht mehr sichtbar ist: Du kommst einfach nicht mehr ran. Doch (ohne ARC) sind die Folgen noch weitreichender: der Speicherplatz, den Dein Objekt einmal eingenommen hat, bleibt weiterhin belegt. Nur weil Du das Objekt nicht mehr sehen kannst (und auch nie wieder ran kommst) bedeutet das ja noch lange nicht, dass es nicht mehr da ist. So ist das Halt mit dem Unsichtbaren: Du siehst es nicht, kannst aber immer noch dagegen laufen. (Erinnern wir uns beispielsweise an die nervenden Spiegel-Glas-Labyrinthe auf den Jahrmärkten unserer Jugend.)

    Insofern musst Du irgend eine in einem weiteren Bereich sichtbare Variable haben, die halt den Wert Deiner Variablen übernimmt.
    Beispielsweise eine dateiweite Person. Fügst Du dieser dateiweiten Person allerdings einen anderen Wert zu (wir erinnern uns: in der Methode neu definieren geht ja nicht) überschreibst Du damit den alten Wert.
    Und auch dann hast Du noch das Problem, dass Du schlimmstenfalls den Speicherplatz nicht freigibst. Also immer schön mit den Settern arbeiten und niemals direkt auf die Variablen zugreifen. ;)

    Wie dem auch sei, genau für die Speicherung von vielen Werten gibt es Collections wie eben NSSet, NSArray und NSDictionary.

    Anstatt bei irgendwelchen Apps im Store zu rätseln, wie die das eventuell gemacht haben könnten, empfehle ich Dir die Seiten von Apple.
    Table View Programming Guide
    (Inklusive Link zu zwei Beispielprojekten)
    Beispielsprojekte; Suchstichwort 'tables'
    «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