| catweasel hat folgendes geschrieben: |
| Was genau ist da eigentlich das Problem damit wenn eine Komponente sich selbst freigeben will |
Ganz einfach. In der MouseUp Methode wird des OnClick aufgerufen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TControl.MouseUp(...); begin MachWasMitMirSelbst; OnClick(Self); MachNochWasMitMirSelbst; end; |
Wenn du nun Self.Free im OnClick-Ereignis aufrufst, wird die Komponente freigegeben und beim zurückkehren in MouseUp crasht das
MachNochWasMitMirSelbst, da es auf die Komponente zugreift.
| Zitat: |
| und kann man für Komponenten auch ein "release" implementieren wie für Forms, wo ja der MessageQueue vor dem destroy abgearbeitet wird....??? |
Natürlich kann man das.
[quoet="TomT"]Oh, fast vergessen. Die Komponente ruft beim .free alle Destruktoren aller Komponenten auf, von denen deine Komponente erbt.[/quote]
Hää? Eine abgeleitete Klasse ruft zwar die Destruktoren der Vorfahrklassen auf (sofern inherited Destroy im Destruktur aufgerufen wird), aber das bedeutet noch lange nicht, dass wenn ich z.B. einen TButton erzeuge auch noch eine TWinControl, TControl und TComponente Komponente "gratis" dazu bekomme, nur weil TButton von TWinControl erbt.
Oder meinst du mit "erbt", den Owner? Das wäre dann aber auch falsch, denn nur wenn der Owner freigegeben wird, wird die Komponente dann auch freigegeben. Also die andere Richtung.
Bzgl. Timer und Lösch-Flag:
| catweasel hat folgendes geschrieben: |
| Der Punkt ist hier die Performance.... Bei einem MemorySet aus 200 Bildern sind das 400 Karten.... Das dauert schon eine Weile.... |
Soll dein Memory-Spiel auf einem 8086 laufen, damit du den Performance unterschied feststellen kannst?
| Zitat: |
| Ein Timer ist nicht zuverlässig. |
Er ist dahingegend zuverlässig, dass man weiß, dass kein einziges Timer-Ereignis ausgelassen wird. Ob es nun 5 ms zu spät kommt ist eher unwichtig. Windows ist nun mal kein Echtzeit Betriebssystem.
| Zitat: |
| Ich kann nicht exakt entscheiden was das ontimer ereignis ausgeführt wird . Damit meine ich das Timerereignis selbst. |
Ich irgendwie schon. Ein Timer Ereignis wird dann ausgeführt, wenn eine WM_TIMER Message in an der Spitze der Messagequeue steht und dieses wird durch Windows generiert und kommt in mehr oder weniger (je nach Rechenbelastung) regelmäßigen Abständen, dem Interval.
| Zitat: |
| Ein Timer funktioniert ja über Nachrichten und da kann schon mal eine verlorengehen bzw. sehr spät ankommen. |
Das eine Message geschluckt wird, kommt nur vor, wenn die Messagequeue voll ist. Dann werden aber als erstes Benutzer-Interface Ereignisse wie Tastatur und Mouse ausgelassen (wenn ich mich nicht irre). Das ist auch der Grund, warum man mit einem Timer die Messagequeue vollstopfen kann, wenn der Code in OnTimer übermäßig lang braucht oder garnicht terminiert.
| Zitat: |
| Ein Timer verbraucht viel resourcen. |
Ein Timer verbraucht kaum resourcen. 100 Timer verbrauchen viele Resourcen, nämlich 100 mal soviel vie
ein Timer.
| Zitat: |
| Ein Timer zu benutzen ist kein guter OOP Stil. |
Kann dir nicht folgen. Seit wann hat die Programmierart mit dem Programmablauf etwas zu tun?
| Zitat: |
Mit einem Timer schaffst du höchstens 10ms-intervall (unter WinNT usw) und ~40ms (?) unter 9x.
Das fällt zwar auch nicht auf, aber ich halte es trotzdem für keinen guten Stil. |
Wieso hat Microsoft denn überhaupt einen Timer programmiert, wenn er doch gar nicht benutzt werden sollte?
| recall hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3:
| S := TimeToStr(Now); Repeat Until S<>TimeToStr(Now); | |
Viel Spaß bei der Endlos Schleife, die neben dem unnötigen TimeToStr auf noch die gesamte CPU mit 100% belastet. Hast du schon einmal gehört, dass man Gleitkommazahlen (was anderes ist TDateTime nicht) auch direkt mit "<" und ">" vergleichen kann?
| catweasel hat folgendes geschrieben: |
| Ein Programm mit Timer ist eben nicht mehr 100% deterministisch aufgebaut. Man kann nicht mehr mit letzter Sicherheit sagen was wann in welcher Reihenfolge ausgeführt wird. |
Und das kann man, wenn der Benutzer seine Input-Ereignisse (Mouse, Tastatur und abhängige Ereignisse) auslöst? Woher willst du z.B. wissen, dass ein Benutzer nach dem Drücken einer Maustaste nicht vor dem Loslassen eine Taste auf der Tastatur drückt? Ein Programm, dass über Botschaften läuft, kann vom Ablauf her nicht deterministisch sein, wenn ein User vorhanden ist, der über Eingabegeräte verfügt.
| Zitat: |
| Was passiert z.b. beim unmittelbaren Klick auf die Karte wenn dann noch ein timerevent die Karte löschen will (weil ein paar gefunden wurde) |
Gar nichts, weil die Ereignisse der Reihe nach abgearbeitet werden.
| Zitat: |
| Oder es ird nur ein paar gelöscht weil das Timerereignis zwischen die "Karte-auf-löschen-setzen) Routine fällt.....? |
So lange du in "Karte-auf-löschen-setzen" kein Application.ProcessMessages aufrufst, wird das Timer-Ereignis erst bei der Rückkehr in die Messageloop ausgeführt und die ist bestimmt nicht in "Karte-auf-löschen-setzen". Sie ist nämlich außerhalb von jeder Komponente (TApplication mal ausgeschlossen).
| Zitat: |
| Es gibt meist immer eine Alternative zu einem Timer. Es gibt nichts wo es "ohne Timer nicht geht".. |
Natürlich gibt es ab Windows 95 sowas nicht mehr. Das aber nur aus dem einen Grund, da man ab Win95 in der Lage ist, das, was Windows für einen Timer im Hintergrund erledigt, auch selbst nachzuprogrammieren. Womit wir bei Threads angelangt sind. Wenn man aber einen Code im "OnThreadTimer" Ereignis hat, der nicht ohne Synchronize auskommt, hat man genau die gleiche Situation geschaffen, die ein Timer durchläuft. Man hat nämlich dann zwei Möglichkeiten: Synchronize aufrufen oder mit PostMessage den Hauptthread über das Ereignis informieren. Wenn man sich nun die Synchronize Methode genauer anschaut, stellt man fest, dass diese vom Prinzip her genaus so arbeitet wie ein PostMessage.
Bzgl. TTimer und OOP:
| Zitat: |
Doooch ich sags ..
Und der Onkel Borland auch |
Wo schreibt Borland das denn?
| Zitat: |
| Ein cast hat immer das Potential schiefzugehen |
Wenn man nicht aufpasst, schon. Aber als Programmierer sollte man seinen Quellcode kommentieren und auch zu jeder Runtime-Zeit wissen, was in welchen Variablen steht (es ist damit
nicht gemeint: welcher Werte genau in der Variable steht).
| Zitat: |
und soll (weiss nich obs stimmt) sehr "langsam", "resourcenfressend" oder sonstwas sein..
Auf jedenfall unvorteilhaft.. |
Natürlich ist der Typecast unvoreilhaft, wenn mein ein solches Bild von ihm hat. Ein direkter Typecast ohne
as verbraucht nicht einen CPU-Tick, da es eigentlich nichts anderes ist als: "Compiler hör mal zu. Du musst die Variable x nun nicht mehr als TObject betrachten, sondern als TComponent." Es wird kein Maschinencode bei einem Typecast erzeugt.
Nur bei "String to PChar" ist das anders, da Delphi-Strings so handlich sind (im Vergleich zu C/C++ (ohne stl)), nimmt der Compiler ein wenig Programmierleistung ab und fügt bei PChar(string) etwas Compiler-Magic ein.
| Zitat: |
| Steht auch so irgendwo in der Delphi Hilfe... |
Da steht höchstens was über den
as-Operator. Ja, dieser ist etwas langsam, da er einen
is-Aufruf durchführt, der "so lange" braucht. Wenn man aber genau weiß, dass die zu castende Variable einen bestimmten Typ hat, kann man direkt casten ohne das
as. Persönlich verwende ich
as nur, wenn es der Lesbarkeit des Quellcodes dienlich ist.
---------------------------
So viel Falsch-Wissen habe ich schon lange nicht mehr gesehen.