Hallo Hagen,
Zitat von
negaH:
Ich weiß nicht welchen Code du von IsObject() von mir analysiert hast.
ich berufe mich auf die
Unit DEC_api vom 26.08.1999 (zugegeben, etwas alt?), in der folgende Abfrage zufinden ist:
if (PInteger(PChar(AObject) - SizeOf(Integer))^ and $00000002 = $00000002)
bevor der Vergleich auf die Klasse stattfindet.
Zitat von
negaH:
Dabei lädt sie die
VMT der Objectinstance und überprüft ab da rekursiv die Klassentypen bis hinab zu TObject.
Diese Implemenentierung konnte ich weder in der DEC_api noch in der DECUtil vom 26.08.1999 mit
if TObject(AObject) is AClass
entdecken.
Die von Dir beschriebene Variante mit der zusätzlichen Prüfung auf
nil erfüllt mit der Möglichkeit auf die Prüfung einer konkreten Schnittstelle (Typen) noch eine zusätzliche Funktion, jedoch arbeitet sie bei zufällig (von
nil verschiedenen) Werten auf zusammenhangslosen Daten fehlerhaft, so dass Du willkürliche Informationen gegen eine übergebene Klassenreferenz testest darüber hinaus nicht ausschließen kannst, in Endlosschleifen "hängenzubleiben", sofern ich das richtig verstanden habe.
Zitat von
negaH:
Man kann noch eine Verbesserung durchführen indem man TObject.FreeInstance() überschreibt oder eben hookt/patcht.
An diesen Ansatz hatte ich auch schon gedacht und entspricht wohl dem, was Touchdown meinte(?). Zumindest für den Fall der gerade freigegebenen Objekte könnte so in einer SingleThread-Anwendung oder bei einer Implementierung des MM, bei der jeder Thread unterschiedliche Bereiche von Speicher zugewiesen bekommt, gelöst werden.
Das Problem sah ich bei dieser Lösung, genau wie Du, bei der erneuten Vergabe (zB durch weiteren Thread), die auch nicht unmittelbar später erfolgen muss, sondern bei Strukturen homogener Klassen auch nach mehrfacher Freigabe und Neuvergabe von Speicher auftreten kann.
Es ist die Frage, ob dies nicht vielleicht sogar gewollt ist, wenn die Routine
IsObject lediglich prüfen soll, ob hinter einer Referenz tatsächlich ein Objekt steht. Es liegt in der Natur der Referenzen, dass sie nicht surjektiv sind, so dass der von Dir beschriebene Fall nicht von einer Zuweisung der Form
myRef:= anotherRef;
unterschieden werden kann (und sollte?).
Es bleibt folglich das Problem der fälschlichen Verarbeitung von zuälligen Daten (auch mit der von mir vorgeschlagenen Prüfung auf die Selbstreferenz einer Klasse nach einer Prüfung auf die Lesbarkeit des Speichers ist dies nur zu einer endlichen Wahrscheinlichkeit möglich) und der zusätzliche Zeitaufwand bei der Freigabe von Objekten (abgesehen davon, dass nicht gerantiert ist, dass die Implementierung von
TObject.FreeInstance aufgerufen wird (NodeManager)).
Weiß jemand weiter?