• Das kreative Thema des Monats Oktober wird vor allem diejenigen unter Euch besonders ansprechen, denen Do-it-yourself quasi im Blut liegt. Zeigt uns Eure Improvisationskünste oder fotografiert, was andere Leute sich so im Alltag zusammengestrickt haben. --> Zum Mitmachen bitte hier klicken

Werteübergabe immer veraltet

bginner

Ingrid Marie
Registriert
13.12.09
Beiträge
266
Hallo zusammen,

Ich starte in meiner App mit einem UIViewController der einen TableView enthält (kein UITableViewController)
Des weiteren hab ich eine Klasse Mitarbeiter mit den Attributen Name, Vorname und Alter. In dem TableView werden die Vornamen der Personen angezeigt. Wählt man eine Person, wird durch einen Segue ein DetailViewController (auch ein UIViewController) aufgerufen und dort durch UILabels noch der Nachname und das Alter angezeigt. Also eigentlich alles ganz Simpel.
Ich habe jezt aber das Problem das
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
vor der Delegate-Methode
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
aufgerufen wird.

Ich poste erstmal nicht dem kompletten Code der Übersicht wegen.

Hier meine prepareForSegue-Methode
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"detailSegue"])
    {
        NSLog(@"Name in Segue : %@", mit.firstName);
        [segue.destinationViewController setAngestellter:mit];
    }
}

Meine didSelectRowAtIndexPath- Methode sieht so aus:
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    mit = [sortedArray objectAtIndex:indexPath.row];
    NSLog(@"Row %d selected with Value %@", indexPath.row, mit.firstName);
}
mit = Ein Objekt der Klasse Mitarbeiter.
Das NSLog sagt mir das die Attribute auch Werte haben und nicht NULL sind.

Das Problem ist jetzt das zuerst die prepareForSegue-Methode aufgerufen wird, also ist dort mit.firstName = NULL. Dementsprechend zeigen die Labels im DetailViewController auch nix an. Wähle ich einen anderen Eintrag aus der Tabelle, zeigen die Labels die Werte des letzten Eintrags an logischer Weise, aber wie kann ich das Problem jetzt lösen.

Ich habe mir ein anderes Beispiel was ich gemacht hatte schonmal angeschaut, da hab ich es genau so gelöst, Allerdings hatte ich dort einen echten UITableViewController aber macht das solch einen Unterschied? Ich hoffe ihr könnt mir helfen.
 
Du hast hier zwei Optionen:

1) Du rufst die Segue programmatisch aus deiner didSelectRowAtIndexPath-Methode auf (sauber)
2) Du setzt die mit-Variable in deinem Zielcontroller in der didSelectRowAtIndexPath-Methode (unsauber, denn dazu muss die Controller-Klasse die das TableView hält deinen Ziel-Controller kennen)

Es ist generell immer besser alle Transitionen zwischen Controllern programmatisch abzufahren.
 
1) Du rufst die Segue programmatisch aus deiner didSelectRowAtIndexPath-Methode auf (sauber)
2) Du setzt die mit-Variable in deinem Zielcontroller in der didSelectRowAtIndexPath-Methode (unsauber, denn dazu muss die Controller-Klasse die das TableView hält deinen Ziel-Controller kennen)
Nein, das ist beides unsauber, weil man alte und neue Konzepte vermischt. Es gibt noch eine dritte, saubere Möglichkeit:
Code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"detailSegue"])
    {
        NSIndexPath *indexPath = [(UITableView *)self.view indexPathForSelectedRow];
        [segue.destinationViewController setAngestellter:[sortedArray objectAtIndex:indexPath.row]];
    }
}
Die Delegate-Methode tableView:didSelectRowAtIndexPath: braucht man für den Wechsel von Views per Segues nicht.

Es ist generell immer besser alle Transitionen zwischen Controllern programmatisch abzufahren.
Warum?

MacApple
 

Weil man dann genau weiß wann etwas in welcher Reihenfolge passiert. Klar, geht auch alles über IB, aber ich habe die Erfahrung gemacht, dass es besser verständlich ist, wenn ich den Code selbst schreibe.

Hast du die von dir vorgeschlagene Lösung ausprobiert? ICH persönlich wüsste nicht, ob zu dem Zeitpunkt prepareForSegue die Selektion im TableView sicher schon aktualisiert wurde. Gibt es hier evtl. nebenläufige Aktionen? Dann könnte es zu Race-Conditions kommen (mal geht's und mal nicht).

Wie gesagt: ICH weiß es nicht. Heißt nicht, dass DU es auch nicht weißt. Aber aus diesem Grund sage ich, es ist besser die Transitionen selbst zu programmieren. Da weiß man was bis dahin bereits passiert ist.
 
Weil man dann genau weiß wann etwas in welcher Reihenfolge passiert. Klar, geht auch alles über IB, aber ich habe die Erfahrung gemacht, dass es besser verständlich ist, wenn ich den Code selbst schreibe.
Bei Deinem Vorgehen finde ich ist überhaupt nicht klar, was wann passiert. Das Storyboard triggert ja die dort angelegten Segues und Du triggerst die im Code dann nochmal?! Wie oft wird bei Dir prepareForSegue:sender: aufgerufen?

Hast du die von dir vorgeschlagene Lösung ausprobiert? ICH persönlich wüsste nicht, ob zu dem Zeitpunkt prepareForSegue die Selektion im TableView sicher schon aktualisiert wurde.
Das Master-Detail Template von Xcode liefert Dir den Code direkt so frei Haus. In der Dokumentation findest Du diese Lösung immer wieder. Zum Beispiel hier.

Gibt es hier evtl. nebenläufige Aktionen? Dann könnte es zu Race-Conditions kommen (mal geht's und mal nicht).
Die Sorge hätte ich eher bei Deiner Methode. Wenn man da was falsch macht, dann pusht man auch schon mal zwei ViewController auf einmal auf den Navigation Stack. Erstelle mal ein neues Projekt mit dem Master-Detail Template und füge dem MasterViewController folgendes hinzu:
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"showDetail" sender:self];
}

Wie gesagt: ICH weiß es nicht. Heißt nicht, dass DU es auch nicht weißt.
Wie gesagt: Steht so in der Dokumentation an diversen Stellen. Die Methode prepareForSegue:sender: ist ja nun mal dazu da, um dem DestinationViewController Informationen übergeben zu können. Wäre ja ziemlich sinnlos, an dem Punkt nicht an die Auswahl heran zu kommen.

Aber aus diesem Grund sage ich, es ist besser die Transitionen selbst zu programmieren. Da weiß man was bis dahin bereits passiert ist.
Dann programmierst Du also ohne Storyboard? Ich mein, wozu bräuchtest Du es sonst noch?

MacApple