Was iss'n da los?

  • Was iss'n da los?

    Ich hab einen simplen Baum (Array) dieser hat Knoten welche ihrerseits auch wieder Unterknoten haben können, soweit alles klar.
    Wenn ich einen Knoten aus dem Baum lösche welcher ein Root-Knoten ist, erhalte ich folgende Ausgabe:

    PHP-Quellcode

    1. 2010-12-20 18:09:24.530 Prog[502:a0f] 0
    2. 2010-12-20 18:09:24.531 Prog[502:a0f] 1
    3. 2010-12-20 18:09:24.531 Prog[502:a0f] delete: Node


    Das passt, der Knoten ist das 3. Element im Baum.

    Wenn ich allerdings einen Knoten lösche, der ein Leaf ist, sprich der in einem Knoten drin ist, erhalte ich das:

    PHP-Quellcode

    1. 2010-12-20 18:09:58.203 Prog[527:a0f] 0
    2. 2010-12-20 18:09:58.204 Prog[527:a0f] 1
    3. 2010-12-20 18:09:58.205 Prog[527:a0f] 2
    4. 2010-12-20 18:09:58.206 Prog[527:a0f] delete: Node
    5. 2010-12-20 18:09:58.207 Prog[527:a0f] 3
    6. 2010-12-20 18:09:58.208 Prog[527:a0f] 4
    7. 2010-12-20 18:09:58.208 Prog[527:a0f] 5
    8. 2010-12-20 18:09:58.209 Prog[527:a0f] 6
    9. ...
    Alles anzeigen


    Hier mal den Code dazu

    PHP-Quellcode

    1. - (IBAction)deleteItem:(id)sender
    2. {
    3. MyNode* item = [outlineView itemAtRow:[outlineView selectedRow]];
    4. MyNode* node = (MyNode*)sender;
    5. static MyNode* parentNode;
    6. if(!parentNode)
    7. parentNode=rootNode;
    8. static int i=0;
    9. for(MyNode* n in [node childs])
    10. {
    11. NSLog(@"%i",i++);
    12. if(n==item)
    13. {
    14. NSLog(@"delete: %@", [n itemName]);
    15. [parentNode deleteChild:n];
    16. return;
    17. }
    18. if ([n hasChildren])
    19. {
    20. parentNode=n;
    21. [self deleteItem:n];
    22. }
    23. }
    24. }
    Alles anzeigen



    was mich stutzig macht ist, dass nachdem der Knoten gelöscht wurde, die Schleife lustig weiter durchlaufen wird, obwohl ich mit nem return rausspringe. Das aber nur wenn ich
    einen Leaf lösche. Ich steh ein wenig auf den Schlauch.
  • ich glaub es liegt daran das du eine Collection veränderst wärend du sie traversierst...
    Achs BTW tritt es beim wiederholtem testen auf? du setzt die static parentnode nie zurück sprich wenn du zb erst einen Knoten löschst zeigt sie auf das rootitem wenn du danach noch ein leaf löschst zeigt sie immer noch darauf bzw auf den alten parent
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von chartus ()

  • Es tritt immer dann auf, wenn ich einen Leaf löschen will, hat für mich mit dem Parent erst mal nix zu tun, ich will mit return raus aus der Methode, egal was da drin passiert.
    Mit parentNode hole ich mir nur den Elternknoten, mehr nicht.
    Mir fehlt da ein wenig der Zusammenhang, ich will einfach nur raus aus der Methode.


    BTW: break, oder eine simple for-Schleife macht exakt das Selbe.
  • Ne, beim Eintritt in die Methode ist parentNode auf jeden Fall rootNode, da kann nix schief gehen.
    Wenn ich in einen Leaf absteige ändert sich parentNode entsprechend, der Wert stimmt auch immer.
  • Hm,

    hm also ich finde das jetzt logisch. Du gehst ja nur aus der rekursiv aufgerufenen Routine mit return raus, kommst dann aber wieder in die gleiche Routine, welche dann die schleife weiter durchläuft.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Das verstehe ich nicht, wie meinst du?

    Achso, jetzt weiß ich was du meinst, ja stimmt, nur wie komme ich komplett raus ??

    vielleicht so??

    PHP-Quellcode

    1. return;
    2. return;
    3. return;
    4. return;
    5. return;
    6. return;
    7. return;

    :D
  • Sorry, habe gerade mit Kunmpel bischen gefeiert und paar Bier intus, also wenn ich voll daneben liege kann passieren, aber

    Ablauf-Diagramm:

    Main ruft auf:
    DeleteItem, zählt i hoch und ruft auf
    DeleteItem, zählt i hoch und kommt zurück mit return nach
    DeleteItem, dass zählt weiter i hoch bis alle n abgearbeitet sind.
    end

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ich versteh was du meinst, im Prinzip liegen x Durchläufe auf dem Stapel, die alle abgearbeitet werden sollen.
    Tja,dann stellt sich trotzdem die Frage, wie komm ich frühzeitig raus?

    Klingt irgendwie komisch
  • Ich hab' jetzt eine Viertelstunde auf Deinen Code gesehen und versucht herauszufinden, was Du damit überhaupt machen willst. Entweder schiele ich oder Du verhaspelst Dich da mit item, node, parentNode und n. Warum ist denn parentNode vor dem Aufruf immer null? Setzt Du das irgendwo? Du gehst die Kinder von node durch, wenn Du item findest, sagst Du aber parentNode, das Kind zu löschen - warum? Irgendwie ist die Benennung etwas unglücklich - die Methode heißt deleteItem:, das Argument wird dann aber zu node und item ist was anderes. Ehrlich: Ich kapier's nicht... Da bleibt nur raten. Ändert ein break statt einem return etwas? Sollte ja eigentlich gehupft wie gesprungen sein. Bist Du sicher, dass das Ganze nicht mehrfach von draußen aufgerufen wird? Dein i zählt ja fröhlich weiter.

    Ich denke, Thallius meinte, dass es bei rekursiven Methoden nicht ungewöhnlich ist, dass man nach einem return wieder in der gleichen Methode landet, wenn die sich selbst aufgerufen hat.
    Multigrad - 360°-Produktfotografie für den Mac
  • Das sollte gehen:

    Quellcode

    1. - (BOOL)deleteItem:(id)sender
    2. {
    3. MyNode* item = [outlineView itemAtRow:[outlineView selectedRow]];
    4. MyNode* node = (MyNode*)sender;
    5. static MyNode* parentNode;
    6. if(!parentNode)
    7. parentNode=rootNode;
    8. static int i=0;
    9. for(MyNode* n in [node childs])
    10. {
    11. NSLog(@"%i",i++);
    12. if(n==item)
    13. {
    14. NSLog(@"delete: %@", [n itemName]);
    15. [parentNode deleteChild:n];
    16. return TRUE;
    17. }
    18. if ([n hasChildren])
    19. {
    20. parentNode=n;
    21. if([self deleteItem:n]==TRUE)
    22. return TRUE;
    23. }
    24. }
    25. return FALSE;
    26. }
    Alles anzeigen


    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ok nochmal der Ablauf:

    Die Methode wird aufgerufen, sender ist der rootNode, dieser beinhaltet alle Elemente.
    rootNode hat kein parent, weshalb die Zuweisung

    PHP-Quellcode

    1. if(!parentNode)
    2. parentNode=rootNode;

    sofort greift.

    Jetzt durchlaufe ich alle Knoten innerhalb eines Knoten, wenn der Knoten weitere Unterknoten hat, rufe ich die Mehtode wieder auf und setzt parent auf
    das aktuelle Element (welches ja Unterknoten hat).

    Verstanden ?? ;)
  • Thallius schrieb:

    Das sollte gehen:

    Quellcode

    1. - (BOOL)deleteItem:(id)sender
    2. {
    3. MyNode* item = [outlineView itemAtRow:[outlineView selectedRow]];
    4. MyNode* node = (MyNode*)sender;
    5. static MyNode* parentNode;
    6. if(!parentNode)
    7. parentNode=rootNode;
    8. static int i=0;
    9. for(MyNode* n in [node childs])
    10. {
    11. NSLog(@"%i",i++);
    12. if(n==item)
    13. {
    14. NSLog(@"delete: %@", [n itemName]);
    15. [parentNode deleteChild:n];
    16. return TRUE;
    17. }
    18. if ([n hasChildren])
    19. {
    20. parentNode=n;
    21. if([self deleteItem:n]==TRUE)
    22. return TRUE;
    23. }
    24. }
    25. return FALSE;
    26. }
    Alles anzeigen


    Gruß

    Claus


    So viel hast du anscheinend nicht getrunken.
    It works ;)

    Danke und lass es dir schmecken.
  • Hi,

    naja reine Trainingssache :)

    Ich programmieren jetzt seit 20 Jahren genau so einen Kram, mit verketteten Listen und Rekurssionen. Glaub mir, die Knoten dich ich schon im Kopf hatte, dagegen ist der gordische Knoten ne einfache Schleife :)

    Und ja, ich mach mir jetzt das nächste Bier auf

    Prost

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)