Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Self.Destroy
Mortal-Shadow - Do 28.05.09 12:14
Titel: Self.Destroy
Hi,
ich wollte wissen was passiert, wenn ich ein Object sich selbst zerstören lasse.
Irgendwie hätte ich einen Fehler erwartet, aber folgendes funktioniert ganz gut:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| unit Unit2;
interface type TTestingclass = class procedure Suicide; private x : integer; end;
implementation uses unit1;
Procedure Testingclass.Suicide; begin self.Destroy; Inc(x); end;
end. |
Funktioniert das, weil der Code abgebrochen wird nach self.destroy, oder ist dass Zufall und ich sollte so etwas vermeiden.
BenBE - Do 28.05.09 12:42
Das ist Zufall, weil der Speicher noch nicht wieder vergeben ist. Sowas bitte unterlassen. Das ist eine Quelle für SEHR SCHWER ZU FINDENDE Fehler (ich kenn jemand, der hat wegen sowas nen Fehler gehabt, der erst nach etwa 4 Wochen nach Programmstart auftauchte ...)
Mortal-Shadow - Do 28.05.09 12:57
Ah gut, vielen Dank.
Habe befürchtet, dass das schiefgehen kann, war mir aber nicht sicher.
delfiphan - Do 28.05.09 13:31
Es ist kein guter Stil, später schwer zu verstehen und nicht zu empfehlen, trotzdem erkläre ich wann du das theoretisch darfst, denn sowas wird teilweise auch im VCL-Code praktiziert.
Du darfst nach dem Destroy noch so viel Code ausführen wie du willst, solange nicht auf Speicher des Objekts (z.B. auf Felder) zugegriffen wird. Du darfst also auf keine privaten Variablen oder sonstiges zugreifen sondern darfst nur noch das, was eine Class-Methode auch dürfte.
Du musst demnach auch sicherstellen, dass deine Methode, die das Objekt zerstört, nicht von einer anderen Methode aufgerufen wurde, die später noch auf das Objekt zugreift.
Die VCL löst das so, in dem sie sich selbst eine Windows-Message postet. Der Handler dieser Message zerstört dann das Objekt.
Da Windows-Messages auf Ebene von TApplication.HandleMessage (oder analog) ausgelöst wird, ist die oben beschriebene verbotene Schachtelung in den meisten Fällen ausgeschlossen.
Es sei denn, du schmückst deinen Code mit Application.ProcessMessages (was man aber meiner Meinung nach sowieso nie tun sollte). Denn dann wird die Destroy-Message nicht mehr auf Ebene von TApplication.ProcessMessage ausgeführt sondern dort wo Application.ProcessMessages steht, d.h. evtl. in irgend einer Methode und wir sind wieder beim gleichen Schachtelungsproblem. Tatsächlich ist es möglich, auf diese Art eine Access Violation in der VCL zu erzeugen.
Was weniger problematisch ist, wenn du deine Methode klar als eine Alternative zu Free erkenntlich machst und diese nur "von aussen" ausführst, genau wie Free selbst. Natürlich gilt auch hier, dass du nach dem Zerstören nicht mehr auf Objektfelder zugreifst.
Fazit: Es ist möglich, aber nur wenn du ganz genau weisst, was du tust und gewisse Fälle ausschliessen kannst. Das dürfte dir vermutlich nur gelingen, wenn du deinen gesamten Code wirklich unter Kontrolle hast.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!