[DUG] How do you free an Object Instance when you have anInterfaceReference?

David Brennan dugdavid at dbsolutions.co.nz
Thu Sep 29 16:03:33 NZST 2005


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 <mailto:stacey at cjntech.co.nz>  

To: NZ Borland <mailto:delphi at ns3.123.co.nz>  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:  <mailto:stacey at cjntech.co.nz>
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/> 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://ns3.123.co.nz/pipermail/delphi/attachments/20050929/ea7f9085/attachment-0001.html


More information about the Delphi mailing list