[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