[DUG] How do you free an Object Instance when you
haveanInterfaceReference?
Todd Martin
toddm at kol.co.nz
Fri Sep 30 10:18:34 NZST 2005
Okay. I didn't consider persistent TMenuItems on the form.
In Stacey's example it's a bit unclear when the TMenuitems are being freed, but I would do the following
MyMenuItem: IMyMenuItem;
... // Do some stuff.
MyMenuItem := RootMenuItem.AddMenuItem('Hello World', HelloWorldClick);
MyMenuItem._AddRef; //increase the reference count to prevent premature destruction
... // Later on
//MyMenuItem.MyFree;
MyMenuItem._Release; //decrement the reference count
{the object is freed when variable MyMenuItem goes out of scope}
Todd.
----- Original Message -----
From: David Brennan
To: 'NZ Borland Developers Group - Delphi List'
Sent: Thursday, September 29, 2005 4:03 PM
Subject: RE: [DUG] How do you free an Object Instance when you haveanInterfaceReference?
Ideally yes.
Unfortunately you can get in trouble if you let a TComponent descendent (eg TMyComponent) which is used normally on your forms (eg streamed from the DFM) free itself when the interface reference count reaches zero. The problem is that the VCL doesn't create your object as an interface and doesn't maintain an interface pointer too it (so ref count = 0). That's OK. but the first time something (ie your code) queries an interface from a TMyComponent (ref count = 1) and then releases the interface (ref count = 0). whoops, there goes your TMyComponent, even though you didn't want to release it and was still necessary for your form.
There are other possible issues, such as keeping interface references to VCL created TComponents and then having the VCL free your component when the form gets freed - even though you still have an interface pointer to it. There are ways around these in specific cases but basically if you want to keep pointers to TComponents then if at all possible they should be as TComponent pointers, with Notify implemented by your owning object, etc (ie the way the VCL does it).
If Stacey is under control of all places where his controls are created, who owns them, etc then fine, but if it is also used as a normal TComponent then I would think twice.
David.
------------------------------------------------------------------------------
From: delphi-bounces at ns3.123.co.nz [mailto:delphi-bounces at ns3.123.co.nz] On Behalf Of Todd Martin
Sent: Thursday, 29 September 2005 3:36 p.m.
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] How do you free an Object Instance when you have anInterfaceReference?
Hi Stacey
You should never "free" an interface.
Implement reference counting in TMenuItem (see TInterfacedObject). The object will be destroyed automatically, when all variables that reference it (eg MyMenuItem) go out of scope.
Todd.
----- Original Message -----
From: Stacey Verner
To: NZ Borland Developers Group - Delphi List
Sent: Thursday, September 29, 2005 3:06 PM
Subject: [DUG] How do you free an Object Instance when you have an InterfaceReference?
If you have an object the implements and interface, and you have a reference
to the interface, how do you free the object using the reference to the interface?
I have the following (simplified) interface and classes.
interface
type
IMyMenuItem = interface
function AddMenuItem(PCaption: String; POnClick: TNotifyEvent): IMyMenuItem;
procedure MyFree;
end;
TMyMenuItem = class(TMenuItem, IMyMenuItem)
public
function AddMenuItem(PCaption: String; POnClick: TNotifyEvent): IMyMenuItem;
procedure MyFree;
end;
TMyTBMenuItem = class(TTBItem, IMyMenuItem)
public
function AddMenuItem(PCaption: String; POnClick: TNotifyEvent): IMyMenuItem;
procedure MyFree;
end;
implementation;
function TMyMenuItem.AddMenuItem(PCaption: String; POnClick: TNotifyEvent): IMyMenuItem;
var
LMenuItem: TMyMenuItem;
begin
LMenuItem := TMyMenuItem.Create(PParent.Owner);
LMenuItem.Caption := PCaption;
LMenuItem.OnClick := POnClick;
Result := LMenuItem;
end;
procedure TMyMenuItem.MyFree;
begin
Free;
end;
function TMyTBMenuItem.AddMenuItem(PCaption: String; POnClick: TNotifyEvent): IMyMenuItem;
var
LMenuItem: TMyTBMenuItem;
begin
LMenuItem := TMyTBMenuItem.Create(PParent.Owner);
LMenuItem.Caption := PCaption;
LMenuItem.OnClick := POnClick;
Result := LMenuItem;
end;
procedure TMyTBMenuItem.MyFree;
begin
Free;
end;
The intention of this is to allow you to dynamically create menu items, but
it doesn't matter if you have a normal menu (TMenuItem) or a
Toolbar 2000 menu (TTBItem). You just deal with IMyMenuItem and the correct
objects are created behind the scenes.
This works pretty well except I have an intermittent access violations when freeing.
MyMenuItem: IMyMenuItem;
... // Do some stuff.
MyMenuItem := RootMenuItem.AddMenuItem('Hello World', HelloWorldClick);
... // Later on
MMyMenuItem.MyFree; // Intermiitent access violation here!
I don't actually like the fact that I have MyFree. It was the only way I could think of doing it at the time.
Stacey
Stacey Verner Ph: +64-9-4154790
Software Developer Fax: +64-9-4154791
DDI: +64-9-4154797
CJN Technologies Ltd. Email: stacey at cjntech.co.nz
PO Box 302-278, North Harbour, Auckland 1330, New Zealand
12 Piermark Drive, North Harbour, Auckland, New Zealand
Visit our website at http://www.cjntech.co.nz/
----------------------------------------------------------------------------
_______________________________________________
Delphi mailing list
Delphi at ns3.123.co.nz
http://ns3.123.co.nz/mailman/listinfo/delphi
----------------------------------------------------------------------------
No virus found in this incoming message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.11.8/113 - Release Date: 27/09/2005
------------------------------------------------------------------------------
_______________________________________________
Delphi mailing list
Delphi at ns3.123.co.nz
http://ns3.123.co.nz/mailman/listinfo/delphi
------------------------------------------------------------------------------
No virus found in this incoming message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.11.8/113 - Release Date: 27/09/2005
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://ns3.123.co.nz/pipermail/delphi/attachments/20050930/5485835d/attachment-0001.html
More information about the Delphi
mailing list