![]() |
ZV bei Freigeben von TObjectList mit Interface
Was stimmt hier nicht?
Delphi-Quellcode:
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Contnrs; type IMyInterface = Interface ['{6D3FE306-CB00-44CC-A8B1-31BF6F06127A}'] function test: String; End; TmyObject = class (TInterfacedObject, IMyInterface) private FDatum: String; public function test: String; constructor Create(AString: TDate); destructor destroy; end; TForm3 = class(TForm) Button1: TButton; Label1: TLabel; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private AList: TObjectList; public end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.Button1Click(Sender: TObject); var lItem: IMyInterface; begin AList.Add(TmyObject.Create(Now)); if Supports(AList.Items[0], IMyInterface, lItem) then // <-- Lasse ich diese Label1.Caption := lItem.test; // zwei Zeilen weg, läufts end; { TmyObject } constructor TmyObject.Create(AString: TDate); begin FDatum := dateToStr(AString); end; destructor TmyObject.destroy; begin ShowMessage('Free!'); end; function TmyObject.test: String; begin Result := FDatum; end; procedure TForm3.Button2Click(Sender: TObject); var i: Integer; begin ShowMessage('Free: ' + IntToStr(AList.Count)); FreeAndNil(AList); // <-- Hier bekomme ich: "Zugriffsverletzung bei Adresse 0067000B. Schreiben von Adresse F0000001." end; procedure TForm3.FormCreate(Sender: TObject); begin AList := TObjectList.Create; end; end. |
Re: ZV bei Freigeben von TObjectList mit Interface
Hallo,
Dein Problem dürfte die Referenzzählung von Interfaces sein: Wenn Du ein Objekt instanziierst, welches ein Interface implementiert, und dieses Objekt nur einer Objektvariable zuweist, dann ist der Referenzzähler null. Wenn Du jetzt ein Supports() machst, dann wird intern mittels QueryInterface das Interface angefordert, der Referenzzähler erhöht und danach wieder vermindert. Folglich fällt er auf Null zurück und das Objekt wird freigegeben. Merke: Niemals Objektreferenzen und Interfacereferenzen mischen (außer Du weißt genau, was Du tust)! Gruß xaromz |
Re: ZV bei Freigeben von TObjectList mit Interface
Zitat:
Schau Dir mal IInterfaceList / TInterfaceList an:
Delphi-Quellcode:
AList: IInterfaceList;
... AList := TInterfaceList.Create; ... // mach was mit AList |
Re: ZV bei Freigeben von TObjectList mit Interface
Danke! :thumb: Sieht nun so aus.
Delphi-Quellcode:
Muss ich da noch irgend was beachten? Oder kann ich das so verwenden? Geht das vielleicht noch einfacher? Ist nur ein abstraiertes Beispiel. ;)
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Contnrs; type IMyInterface = Interface(IInterface) ['{6D3FE306-CB00-44CC-A8B1-31BF6F06127A}'] function test: String; End; TmyObject = class (TInterfacedObject, IMyInterface) private FDatum: String; public function test: String; constructor Create(AString: TDate); destructor destroy; end; TForm3 = class(TForm) Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private AList: IInterfaceList; public end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.Button1Click(Sender: TObject); var lItem: IMyInterface; begin AList := TInterfaceList.Create; AList.Add(TmyObject.Create(now)); if Supports(AList.Items[0], IMyInterface, lItem) then ShowMessage( lItem.Test ); end; { TmyObject } constructor TmyObject.Create(AString: TDate); begin FDatum := dateToStr(AString); end; destructor TmyObject.destroy; begin ShowMessage('Free!'); end; function TmyObject.test: String; begin Result := FDatum; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz