AW: Umgang mit Interfaces
Ändere einfach in deinem Ausgangspost fMy von TMyClasses auf IInterface und benutz dann die Version mit Supports (GUIDs auf den Interfaces nicht vergessen) - dann zerbröselt es dir deine Referenzzählung nicht.
|
AW: Umgang mit Interfaces
Oder sogar doppelt ... falls die Basis-Instanz als Klasse benötigt wird
Delphi-Quellcode:
Und beim Destroy von TListData einfach mal nicht die Objekt-Instanz befreien :)
TListData = class
private fAsIntf : IInterface; fAsObj: TMyClasses; fName: String; fHash: Cardinal; public property AsIntf : IInterface read fAsIntf; property AsObj : TMyClasses; property Name : string read fName; property Hash : Cardinal read fHash; End; |
AW: Umgang mit Interfaces
Zitat:
Was unter der Überschrift "Warnung" als kryptischer 53 Wörter Satz steht, heißt nicht weiter als: "Pass ja auf wenn du Interface- mit Objektreferenzen mischt, dass kann nämlich ganz schön in die Hose gehen wenn du mit Supports arbeitest." Auch hier gilt: Nicht die Supports-Funktion ist schlecht oder fehlerhaft, sondern der Programmierer hat einen Fehler gemacht! Um beim Beispiel zu bleiben, das hier funktioniert so wie es soll:
Delphi-Quellcode:
Während das hier schief geht, wenn in DoSomeThing auf objekteigene Werte zugegriffen wird, denn die sind dann schon freigeben und genullt:
var
MySomeThingObject : ISomeThing; // <--- das ist so richtig begin MySomeThingObject := TMyDoSomething.Create; if Supports(MySomeThingObject, IInteger) then begin ShowMessage('IInteger wird voll unterstützt!!!'); end; MySomeThingObject.DoSomeThing; end;
Delphi-Quellcode:
var
MySomeThingObject : TMyDoSomething; // <--- da ist die entscheidene Stelle, Fehler!!! begin MySomeThingObject := TMyDoSomething.Create; if Supports(MySomeThingObject, IInteger) then begin ShowMessage('IInteger wird voll unterstützt!!!'); end; MySomeThingObject.DoSomeThing; end; |
AW: Umgang mit Interfaces
Zitat:
Eine solidere Lösung wäre einen Compiler zu verwenden, der besser ist (z.B. FreePascal mit "Corba-Interfaces"). Wenn man bei Delphi bleibt muss man eben den unsichtbaren Refenz-Zähler Kram so gut es geht aushebeln und höllisch aufpassen. P.S: Zur Laufzeit mit Supports zu arbeiten ist etwas, was man so gut es geht vermeiden sollte. Eine Haupterrungenschaft der Objektorientierung war, dass man statt mit schwammigen Pointern jetzt mit feste Typen arbeiten kann. Wenn man jetzt wieder anfängt zur Laufzeit Pointer herumcasten ist das irgendwie sehr Retro. |
AW: Umgang mit Interfaces
Zitat:
Zitat:
|
AW: Umgang mit Interfaces
Zitat:
Die "automatische" Referenzverwaltung von Inferface-Objekten ist in meinen Augen sehr bequem und ermöglicht ein sehr komfortables modernes programmieren. Ähnliches wurde ja im Next-Gen-Compiler für mobile Platformen von Emba umgesetzt. Zitat:
Oft liegt der Fall vor, dass ein Objekt zwei bis drei Interfaces implementiert. Je nachdem muss man dann zwangsläufig testen, ob ein bestimmtes Interface unterstützt wird. Siehe auch die obigen Beispiele. Hast du nur ein Objekt von Typ IInteger vorliegen, musst aber schauen ob ISomeThing unterstützt wird (oder umgekehrt) -> wie sollte man es sonst machen? |
AW: Umgang mit Interfaces
Eine Frage zum Verständnis für jemanden, der mit Interfaces noch nie zu tun hatte:
Delphi-Quellcode:
Sehe ich das richtig, das mein
var
MySomeThingObject : ISomeThing; // <--- das ist so richtig begin MySomeThingObject := TMyDoSomething.Create; if Supports(MySomeThingObject, IInteger) then begin ShowMessage('IInteger wird voll unterstützt!!!'); end; MySomeThingObject.DoSomeThing; end;
Delphi-Quellcode:
bei Verlassen der Prozedur automatisch freigegeben wird, obwohl ich zuvor mit
MySomeThingObject
Delphi-Quellcode:
Speicher dafür alloziert habe ?
TMyDoSomething.Create;
|
AW: Umgang mit Interfaces
Wenn in TMyDoSomething Referenzzählung enthalten ist (z.B. weil von TInterfacedObjekt abgelitten), dann ja, wird es bei Erreichen von 0 Referenzen automatisch freigegeben.
|
AW: Umgang mit Interfaces
Und da die einzige Referenz darauf eine lokale Variable war, ist der Referenzzähler beim Verlassen der Methode Null.
Nicht nur beim normalen Verlassen, natürlich auch, wenn deine Methode mittendrin per Exception rausfliegt. Damit spart man sich das ganze nervige
Delphi-Quellcode:
-Geraffel.
try..finally..Destroy
|
AW: Umgang mit Interfaces
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:31 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz