Weak interface references in earlier versions of Delphi

Hi,

I am working on component which need to be supported in earlier version of Delphi (starting from Delphi 6) and I have problem with reference counting of interfaces.

Last days I am trying to learn more about this topic, and I have collected this info:

- XE2 (or maybe XE3) include [weak] attribute, but I need to support very old Delphi 6.
- At few places I have read that if I declare variable as pointer, RefCount will not be incremented. There are some traps with this approach (which I already discovered :( ), but it seems that this approach work when I assign value. But, as soon I cast this pointer into required interface - RefCount is increased. Please check bellow in code (marked with <----).
- I have found some more elegant solutions, but unfortunately they are using generics and are for more new Delphi versions.
- I can't use third-party libs since I need to ship code as commercial product.

Maybe there is some other approach which I don't know. I am not sure is it possible at all to cast, but to avoid increment. Maybe I don't see something obvious (or I brake some basic rule), in last days I am only surfing trough Delphi VCL code - all day :)

Please help. Thank you in advance.

{code}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  IChild = interface;

  IParent = interface
    ['{49945A1E-AEAA-4A74-9301-F630AE0D5BC7}']
    procedure SetChild(AChild: IChild);
    procedure Test;
  end;

  IChild = interface
    ['{D1B60E54-DF55-4F56-8560-D36F3095FB9C}']
    function GetParent: IParent;
    procedure SetParent(AParent: IParent);
    procedure Test;
    property Parent: IParent read GetParent;
  end;

  TParent = class(TInterfacedObject, IParent)
  public
    FChild: IChild;
    procedure SetChild(AChild: IChild);
    procedure Test;
    destructor Destroy; override;
  end;

  PParent = ^IParent;

  TChild = class(TInterfacedObject, IChild)
  private
    FParent: PParent;
    function GetParent: IParent;
  public
    procedure SetParent(AParent: IParent);
    procedure Test;
    destructor Destroy; override;
    property Parent: IParent read GetParent;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  P: IParent;
  C, D: IChild;

implementation

{$R *.dfm}

{ TParent }

destructor TParent.Destroy;
begin
  ShowMessage('Parent Destroying');
  inherited;
end;

procedure TParent.SetChild(AChild: IChild);
begin
  if FChild <> nil then FChild.Test;
  FChild := AChild;
end;

procedure TParent.Test;
begin
  ShowMessage('Parent: ' + IntToStr(FRefCount));
end;

{ TChild }

destructor TChild.Destroy;
begin
  ShowMessage('Child Destroying');
  inherited;
end;

function TChild.GetParent: IParent;
begin
  Result := IParent(FParent); // <----------------- increase RefCount
end;

procedure TChild.SetParent(AParent: IParent);
begin
  FParent := PParent(AParent);
end;

procedure TChild.Test;
begin
  ShowMessage('Child: ' + IntToStr(FRefCount));
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  C := TChild.Create;
  P := TParent.Create;

  C.SetParent(P); // Does not increase RefCount

  P.Test;

  C.Parent.Test; // Access to Parent property increase RefCount

  C.Test;
  P.Test;

  P := nil;
  C := nil;
end;

end.
{code}
0
Bojan
7/2/2014 5:14:36 PM
embarcadero.delphi.oodesign 456 articles. 0 followers. Follow

20 Replies
892 Views

Similar Articles

[PageSpeed] 8

Bojan wrote:

> - XE2 (or maybe XE3) include [weak] attribute, but I need to support
> very old Delphi 6.

You will have to use manual Pointer type-casts.  There is no other option 
in pre-[weak] versions.

> - At few places I have read that if I declare variable as pointer,
> RefCount will not be incremented. There are some traps with this
> approach (which I already discovered :( ), but it seems that this
> approach work when I assign value. But, as soon I cast this pointer
> into required interface - RefCount is increased. Please check bellow
> in code (marked with <----).

Type-casting a Pointer into an interface does not increment the reference 
count.  Assigning an interface variable to another interface variable increments 
the reference count.  Your code is doing such an assignment (you are assigning 
an interface to a function Result), that is why the reference count is being 
incremented, and that is correct behavior.  You WANT the function Result 
to increment its reference count, because the caller is going to call Release() 
when it is done using the Result, so you don't want the returned object to 
be freed prematurely.

You should be using weak referencing inside of the implementation class fields, 
not in function parameter/Result values, eg:

{code}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
Dialogs, StdCtrls;

type
  IChild = interface;

  IParent = interface
    ['{49945A1E-AEAA-4A74-9301-F630AE0D5BC7}']
    procedure SetChild(AChild: IChild);
    procedure Test;
  end;

  IChild = interface
    ['{D1B60E54-DF55-4F56-8560-D36F3095FB9C}']
    function GetParent: IParent;
    procedure SetParent(AParent: IParent);
    procedure Test;
    property Parent: IParent read GetParent;
  end;

  TParent = class(TInterfacedObject, IParent)
  public
    FChild: IChild;
    procedure SetChild(AChild: IChild);
    procedure Test;
    destructor Destroy; override;
  end;

  TChild = class(TInterfacedObject, IChild)
  private
    FParent: IParent;
    function GetParent: IParent;
  public
    procedure SetParent(AParent: IParent);
    procedure Test;
    destructor Destroy; override;
    property Parent: IParent read GetParent;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  P: IParent;
  C, D: IChild;

implementation

{$R *.dfm}

{ TParent }

destructor TParent.Destroy;
begin
  ShowMessage('Parent Destroying');
  inherited;
end;

procedure TParent.SetChild(AChild: IChild);
begin
  if FChild <> nil then FChild.Test;
  FChild := AChild;
end;

procedure TParent.Test;
begin
  ShowMessage('Parent: ' + IntToStr(FRefCount));
end;

{ TChild }

destructor TChild.Destroy;
begin
  ShowMessage('Child Destroying');
  inherited;
end;

function TChild.GetParent: IParent;
begin
  Result := FParent;
end;

procedure TChild.SetParent(AParent: IParent);
begin
  Pointer(FParent) := Pointer(AParent); // <-- does not increment reference 
count
end;

procedure TChild.Test;
begin
  ShowMessage('Child: ' + IntToStr(FRefCount));
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  C := TChild.Create;
  P := TParent.Create;
  C.SetParent(P);

  P.Test;

  C.Parent.Test;

  C.Test;
  P.Test;
  P := nil;
  C := nil;
end;

end.
{code}



Alternatively:

{code}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
Dialogs, StdCtrls;

type
  IChild = interface;

  IParent = interface
    ['{49945A1E-AEAA-4A74-9301-F630AE0D5BC7}']
    procedure SetChild(AChild: IChild);
    procedure Test;
  end;

  IChild = interface
    ['{D1B60E54-DF55-4F56-8560-D36F3095FB9C}']
    function GetParent: IParent;
    procedure SetParent(AParent: IParent);
    procedure Test;
    property Parent: IParent read GetParent;
  end;

  TParent = class(TInterfacedObject, IParent)
  public
    FChild: IChild;
    procedure SetChild(AChild: IChild);
    procedure Test;
    destructor Destroy; override;
  end;

  TChild = class(TInterfacedObject, IChild)
  private
    FParent: Pointer;
    function GetParent: IParent;
  public
    procedure SetParent(AParent: IParent);
    procedure Test;
    destructor Destroy; override;
    property Parent: IParent read GetParent;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  P: IParent;
  C, D: IChild;

implementation

{$R *.dfm}

{ TParent }

destructor TParent.Destroy;
begin
  ShowMessage('Parent Destroying');
  inherited;
end;

procedure TParent.SetChild(AChild: IChild);
begin
  if FChild <> nil then FChild.Test;
  FChild := AChild;
end;

procedure TParent.Test;
begin
  ShowMessage('Parent: ' + IntToStr(FRefCount));
end;

{ TChild }

destructor TChild.Destroy;
begin
  ShowMessage('Child Destroying');
  inherited;
end;

function TChild.GetParent: IParent;
begin
  Result := IParent(FParent);
end;

procedure TChild.SetParent(AParent: IParent);
begin
  FParent := Pointer(AParent); // <-- does not increment reference count
end;

procedure TChild.Test;
begin
  ShowMessage('Child: ' + IntToStr(FRefCount));
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  C := TChild.Create;
  P := TParent.Create;
  C.SetParent(P);

  P.Test;

  C.Parent.Test;

  C.Test;
  P.Test;
  P := nil;
  C := nil;
end;

end.
{code}

--
Remy Lebeau (TeamB)
0
Remy
7/2/2014 6:36:07 PM
Hi Remy,

Thank you for your answer.

More specific, I have problem inside IParent destructor.

Inside destructor IParent RefCount is already 0 (this is why destructor is called) and if I access to the this object again, it goes from 0 to 1, and back to 0 (on method exit) which call Destructor again. Maybe this can be avoided somehow?

Will try to think about all once again, my brain have melted last days :)
0
Bojan
7/2/2014 6:54:05 PM
Bojan wrote:

> Inside destructor IParent RefCount is already 0 (this is why
> destructor is called) and if I access to the this object again, it
> goes from 0 to 1, and back to 0 (on method exit) which call
> Destructor again. Maybe this can be avoided somehow?

Why are you accessing the parent object from inside its own destructor using 
an interface instead of its own Self pointer?  What are you actually doing 
that is causing the reference count to get bumped?  Please show your real 
code, becaue what you showed earlier does not do that.

--
Remy Lebeau (TeamB)
0
Remy
7/2/2014 7:08:24 PM
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Why are you accessing the parent object from inside its own destructor using 
> an interface instead of its own Self pointer?  What are you actually doing 
> that is causing the reference count to get bumped?  Please show your real 
> code, becaue what you showed earlier does not do that.

Parent is clearing Childs, and in this process Child access to the Parent which causes this Destructor -> 0 -> 1 -> 0 -> Destructor problem.

Code is quite long (starting being complex) and I have created this small project as playground to isolate problem and learn more.

Maybe I need to rewrite this part of code.
0
Bojan
7/2/2014 7:18:37 PM
Bojan wrote:

> Parent is clearing Childs, and in this process Child access to the
> Parent which causes this Destructor -> 0 -> 1 -> 0 -> Destructor
> problem.

Then the child should not be using its Parent property, which bumps the refcount 
(and you cannot avoid that), but should instead be using its FParent field 
directly.

--
Remy Lebeau (TeamB)
0
Remy
7/2/2014 7:29:53 PM
> {quote:title=Remy Lebeau (TeamB) wrote:}{quote}
> Bojan wrote:
> 
> > Parent is clearing Childs, and in this process Child access to the
> > Parent which causes this Destructor -> 0 -> 1 -> 0 -> Destructor
> > problem.
> 
> Then the child should not be using its Parent property, which bumps the refcount 
> (and you cannot avoid that), but should instead be using its FParent field 
> directly.
> 
> --
> Remy Lebeau (TeamB)

Hi,

It seems that I will end with this :( . Thank you again for your help. I will review my code in next days. Learned something new.

At the end, is there maybe some library or custom implementation of IInterfacedObject which somehow emulate weak references and they can be used in early version of Delphi?

Thanks.
0
Bojan
7/2/2014 7:38:52 PM
<Bojan Nikolic> wrote
>
> Maybe there is some other approach which I don't know. I am not sure is it 
> possible at all to cast, but to avoid increment.

Rather than going down in to the technical details...

Exactly how do you want the lifetime semantics to work? There are a variety 
of different hacks/approaches, including descending from a non-refcounted 
interfaced object or IFDEF-ing your code by version.

What's best depends entirely on a complete and consistent definition of what 
you consider 'correct' (aka desired) behavior, and that being crystal clear 
in your mind.

bobD
0
Robert
7/3/2014 3:27:28 AM
> {quote:title=Robert Dawson wrote:}{quote}
> <Bojan Nikolic> wrote
> >
> > Maybe there is some other approach which I don't know. I am not sure is it 
> > possible at all to cast, but to avoid increment.
> 
> Rather than going down in to the technical details...
> 
> Exactly how do you want the lifetime semantics to work? There are a variety 
> of different hacks/approaches, including descending from a non-refcounted 
> interfaced object or IFDEF-ing your code by version.
> 
> What's best depends entirely on a complete and consistent definition of what 
> you consider 'correct' (aka desired) behavior, and that being crystal clear 
> in your mind.
> 
> bobD

Hi Robert,

In my project , I only have a IParent (I named it INode) which have a childs of INode. 

I want that parent node hold a strong reference to childs, but childs to hold a weak reference to parent. Notice here that are both of same interface type. 

I have think about creating my own TInterfacedObject, but I am not sure how this dangerous is. Maybe there is some tested code sample already.

Maybe something like, if possible at all:

{code}
var
  ParentNode: INode;
  ChildNode: INode;
begin
  ParentNode.AssignStrong(OtherNod); // AddRef/Release are used now
  ChildNode.AssignWeak(OtherNode); 
{code}
0
Bojan
7/3/2014 9:45:24 AM
PS. If needed, I may post shortly how my component actually work with interfaces. Maybe it will help.
0
Bojan
7/3/2014 10:05:36 AM
> {quote:title=Bojan Nikolic wrote:}{quote}
> 
> I want that parent node hold a strong reference to childs, but childs to hold a weak reference to parent. Notice here that are both of same interface type. 

Okay, given that circumstance, Remy's absolutely right that the standard pattern would be for the parent to hold an interface reference to the child, and the child a plain pointer reference to the parent.

Since the child's lifetime is guaranteed by the parent, is there any way for a child to be destroyed other than by telling the parent to drop it from the collection? I'm also a bit puzzled that the child would have to call/access the parent in its destructor. Might be some logic there that needs moved.

bobD
0
Robert
7/3/2014 11:44:25 AM
Hi,

It seems that I will end up with using Pointers.

Maybe you will have some more ideas, if I try to explain how my component work. It is a Grid control with rows, where each rows may have own rows. Also each row contain a list of Cells.

{code}
Grid
  |
Row 0
  |-----Row 0.0
          |-----Cell 0, Cell 1, Cell 2, Cell 3
Row 1
Row 2
....
Row n
{code}

- Grid is pointing to Row
- Row is pointing to child row (RefCount 1)
- Each Cell is pointing back to child row (RefCount 1 + number of cells)

In this pattern, if I want to destroy Row 0.0 , I need to destroy cells _first_, if I want to destroy child row. I will more like to destroy cells in Row's destructor. As you both suggested I will try with Pointer, but if there is some more elegant solution - I will listen.

This my problem is not stopping me to progress with project, but all will be easier if there was [weak] attribute in old Delphi's
0
Bojan
7/3/2014 1:57:12 PM
Bojan Nikolic wrote:

> Hi,
> 
> I am working on component which need to be supported in earlier
> version of Delphi (starting from Delphi 6) and I have problem with
> reference counting of interfaces.
> 
> Last days I am trying to learn more about this topic, and I have
> collected this info:
> 
> - XE2 (or maybe XE3) include [weak] attribute, but I need to support
> very old Delphi 6.

Only for the mobile compilers, and only for objects.

You can simply have a weak reference to an interface by declaring it as
a pointer and casting it to the desired interface type when using it.

-- 
Rudy Velthuis (TeamB)    http://www.teamb.com

"The good Christian should beware of mathematicians and all
 those who make empty prophecies. The danger already exists that
 mathematicians have made a covenant with the devil to darken
 the spirit and confine man in the bonds of Hell."
 --Saint Augustine
0
Rudy
7/8/2014 11:46:54 PM
Hi again,

I have spend last days (weeks) dealing with interfaces and all summed into ONE situation:

1) In my component I have object implementing IMyInterface
2) At on point, there are no more references to the object and *destructor* is called. Inside destructor, RefCount is 0. All is ok up to this point.
3) Now, inside destructor I want to call some method where I need to pass *Self as IMyInterface*. For example I want to notify control to repaint, and similar.
4) At this point RefCount is increased to 1, then at exit is back to 0 in which point *destructor* is called _again_, even if original destructor is not finished.

This situation caused me a ton of headaches. Maybe I can solve this by having Boolean flags to detect if Destructor is already running, but maybe there is a more elegant solution.

I am thinking about implementing my own TInterfacedObject where I will have property name eg. StopRefCounting: Boolean , but can somebody tell me how safe is this at all? Maybe I can simply stop RefCount inside this object when destructor is already run.

Many thanks, and please sorry for any beginner questions or thoughts. It starting to be more clear to me, all with interfaces - but not completely.

> {quote:title=Rudy Velthuis (TeamB) wrote:}{quote}
> Bojan Nikolic wrote:
> 
> > Hi,
> > 
> > I am working on component which need to be supported in earlier
> > version of Delphi (starting from Delphi 6) and I have problem with
> > reference counting of interfaces.
> > 
> > Last days I am trying to learn more about this topic, and I have
> > collected this info:
> > 
> > - XE2 (or maybe XE3) include [weak] attribute, but I need to support
> > very old Delphi 6.
> 
> Only for the mobile compilers, and only for objects.
> 
> You can simply have a weak reference to an interface by declaring it as
> a pointer and casting it to the desired interface type when using it.
> 
> -- 
> Rudy Velthuis (TeamB)    http://www.teamb.com
> 
> "The good Christian should beware of mathematicians and all
>  those who make empty prophecies. The danger already exists that
>  mathematicians have made a covenant with the devil to darken
>  the spirit and confine man in the bonds of Hell."
>  --Saint Augustine
0
Bojan
7/16/2014 8:24:14 PM
<Bojan Nikolic> wrote

> 1) In my component I have object implementing IMyInterface

So the structure is

<code>
TYourComponent = class(TComponent)
private
  FInternalObject = class(TInterfacedObject) //implements IMyInterface
....
end;
</code>

?

I'm trying to understand how and why
> 2) At one point, there are no more references to the object
that happens.

If the above is correct, replace or augment the FInternalObject reference so 
that the owning component also holds an interface reference to its internal 
component. That way its refcount never drops below 1 while the owner exists. 
Then when the outer component is destroyed, it can nil the internal 
reference in its destructor, triggering the destruction of the internal 
element as well.

If that's not the structure, then you're going o have to be more specific 
about your code.

bobD
0
Robert
7/16/2014 11:54:18 PM
Bojan Nikolic wrote:

> Hi again,
> 
> I have spend last days (weeks) dealing with interfaces and all summed
> into ONE situation:
> 
> 1) In my component I have object implementing IMyInterface
> 2) At on point, there are no more references to the object and
> destructor is called. Inside destructor, RefCount is 0. All is ok up
> to this point.  
> 3) Now, inside destructor I want to call some method
> where I need to pass *Self as IMyInterface*. For example I want to
> notify control to repaint, and similar.  

That is an absolute no-no if you control lifetime via interface ref
counting. If you cannot pass self as an object reference in this
situation the only way out  I can think of (if you cannot redesign to
avoid this requirement altogether, which would be best) is to create an
instance of a small helper class that also implements the interface in
question and knows the affected class. You create it in the destructor
with Self as object reference passed to the constructor. The methods of
the helper class that implement the interface method then just call the
methods of the object via the reference stored by the constructor. You
then pass the interface reference of the helper to the method in
question.

Quick sketch of this setup: (typed into the message editor, not tested
in any way!):

type
  IMYInterface = interface
  [a guid here]
     procedure Foo;
   end;

   TProblemClass = class(TInterfacedObject, IMyInterface)
   protected
      procedure Foo;  //implements IMyInterface.Foo;
   public
      destructor destroy; override;
   end;

implementation

type
   TProblemSolver   = class(TInterfacedObject, IMyInterface)
   private
      FRef: TProblemClass;
   protected
      procedure Foo;  //implements IMyInterface.Foo;       
    public
      constructor Create(aRef: TProblemClass);
    end;

constructor TProblemSolver.Create(aref: TProblemClass);
begin
   inherited Create;
   FRef := aref;
end;

procedure TProblemsolver.Foo;
begin
   FRef.Foo
end;

destructor TProblemClass.destroy;
begin
    SomeProcRequiringAIMyInterface(
       TProblemSolver.Create(Self) as IMyInterface );
    inherited;
end;

-- 
Peter Below (TeamB)
0
Peter
7/17/2014 5:35:08 PM
Thank you guys,

I will read all carefully and do some tests again and then back to topic.
0
Bojan
7/17/2014 5:54:14 PM
Hi,

I have made to clean up some things. Needed to rewrite big part of code :(

I have one last question please.

Sometimes, I am implementing interface on TWinControl class (e.g. TEdit):

{code}
  IMyIntf = interface
    ['{138A2945-AA8C-40A5-A902-B07030D61FC5}']
  end;

  TMyObj = class(TEdit, IMyIntf)

  end;

  TForm1 = class(TForm)
  ...
    MyObj: IMyIntf;
  end;
....
  MyObj := TMyObj.Create;
{code}

Can you please tell me what is a correct way to destroy/release this object? As far I can see TComponent descendants doesn't support reference counting. If I step into TComponent._Release I may see this.

Since TComponent always include Owner, is Owner responsive for destroying them? If so, how he do this?

Thank you, and please sorry for all this stupid questions last weeks. If I can somehow give you back to you all guys, I may give you free copy of my controls.
0
Bojan
7/20/2014 5:28:37 AM
Bojan Nikolic wrote:

> Hi,
> 
> I have made to clean up some things. Needed to rewrite big part of
> code :(
> 
> I have one last question please.
> 
> Sometimes, I am implementing interface on TWinControl class (e.g.
> TEdit):
> 
> {code}
>   IMyIntf = interface
>     ['{138A2945-AA8C-40A5-A902-B07030D61FC5}']
>   end;
> 
>   TMyObj = class(TEdit, IMyIntf)
> 
>   end;
> 
>   TForm1 = class(TForm)
>   ...
>     MyObj: IMyIntf;
>   end;
> ...
>   MyObj := TMyObj.Create;
> {code}
> 
> Can you please tell me what is a correct way to destroy/release this
> object? 

If you create it with an Owner then the owner will destroy it when it
is itself destroyed. However, you can free it before that, if needed.
The crucial thing in this setup is this: you have to make sure that
there are *no* variables holding interface references to the component
around anymore when it is destroyed. Otherwise the interface reference
may go out of scope later, and the compiler will have made sure that
_Release is called when that happens. And that will likely cause an
access violation since the object that implements the interface is
already dead.



-- 
Peter Below (TeamB)
0
Peter
7/20/2014 9:48:23 AM
Bojan wrote:

> Can you please tell me what is a correct way to destroy/release this
> object?

The easiest way is to simply assign an Owner to the object, and let the Owner 
free it for you when the Owner is freed.  You just have to make sure the 
interace is nil'ed first, otherwise it may try to call _Release() on a non-existant 
object.  You can use the form's OnDestroy event for that, eg:

{code}
procedure TForm1.FormCreate(Sender: TObject);
begin
  MyObj := TMyObj.Create(Self);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  MyObj := nil;
end;
{code}

> Since TComponent always include Owner, is Owner responsive for
> destroying them?

Yes.

> If so, how he do this?

TComponent has an internal list of components that it owns.  When a TComponent 
is freed, it removes itself from its Owner's list, and frees all of the components 
in its own list.

--
Remy Lebeau (TeamB)
0
Remy
7/20/2014 5:26:27 PM
Thanks again,

What should I do if I need to delete/create object several times in my control. In my example I have a TEdit descendant who need to be created when edit starts and destroyed when user finish with editing.

1) In this case how to I delete actual instance of interface?

Do I need to do something like :

{code}(MyObj as TEdit).Free;{code}

or

{code}MyObj.Instance.Free;{code}

But if Owner is set, I will need to remove instance from Components list of Owner? In my test ComponentCount of Own is increased after every creation and never decreased (except when destroyed).

2) Is it safe to init this object without Owner:

{code}MyObj := TMyObj.Create(nil);{code}

and then not to bother with removing object from Components list of Owner.

I am able to destroy object (without any leaks and AV's) in this way but it don't look very nice:

{code}
procedure TForm3.Button2Click(Sender: TObject);
var
  T: TMyObj;
begin
  FMyObj := TMyObj.Create(nil);

  T := (FMyObj as TMyObj);

  FMyObj := nil;

  T.Free;
  T := nil;
end;
{code}

PS. If someone of you guys want my components for free, please contact me on PM.

Thanks!
0
Bojan
7/20/2014 9:37:19 PM
Reply:

Similar Artilces:

Nice, Delphi XE includes free access to earlier version licenses and downloads for Delphi 2010, 2009, 2007 and 7.
Looking at the details for Delphi XE Professional while checking the prices etc and found the above as part of a paragraph. "Delphi XE includes free access to earlier version licenses and downloads for Delphi 2010, 2009, 2007 and 7. Details will be included with your order confirmation email and in the product readme." Very nice bonus! Brian > {quote:title=Brian Evans wrote:}{quote} > Looking at the details for Delphi XE Professional while checking the > prices etc and found the above as part of a paragraph. > > "Delphi XE includes free acce...

DP Delphi-Reference, Meta-Searchengine for Delphi
Hi *.*, I have just revived an old project, a meta-searchengine for Delphi: http://ref.dp200x.de it searches simultaneous: * delphi 2009 online-help hosted by embarcadero * msdn-library psdk (win32) * delphi-praxis codelibrary: ready-to-use code-snippets from one of germanys largest delphi-communities * delphi-praxis forums This project is still in progress and particularly help-content from delphi 2010 is (yet) missing. Content from MSDN needs to be complemented (expanded). Anyway - I think that searching the reference(s) AND realworld-examples in just a single click gi...

Delphi and Delphi for .Net
It seems that Delphi for .Net is slower than Delphi Win32 native applicaiton. I would like to know is it true all .Net application is slower than Win32 native applicaiton or it is Delphi for .Net only. Your information is great appreciated, Inung On 2011-06-21 18:20:17 +0100, Inung Huang said: > It seems that Delphi for .Net is slower than Delphi Win32 native applicaiton. > I would like to know is it true all .Net application is slower than > Win32 native applicaiton or it is Delphi for .Net only. If you are only running the code in the application once then, yes, yo...

Will Delphi XE2 co-exist with other Delphi versions ?
Can I install it on a machine that's got other Delphi's on it ? Lut Mentz wrote: > Can I install it on a machine that's got other Delphi's on it ? Yes. As far as I know that has always been the case. -- -Mike (TeamB) Lut Mentz wrote: > Can I install it on a machine that's got other Delphi's on it ? Yes -- it has always been the case that the new version co-exists peacefully with all the older ones. -- Nick Hodges -- Product Development Manager Gateway Ticketing Systems http://www.gatewayticketing.com > {quote:title=Mike Williams ...

HELP! Trying to Complie old Delphi program on any version of Delphi
Hey everyone I'm new to the programming world and unfortunately I have come across a big problem that I will hope I can get some help with. I have a program that was apparently created using delphi 3 and then finished using delphi 4 with some additional parts added later. I have found copies of amost every version of delphi ever made and installed them on my pc and attempted to compile this program in question. Unfortuantely I have yet to get it to compile without a few thousand error messages and I am st uck between a rock and a hard place. I know very little of Delphi programming, let a...

Why are you not upgrading from earlier versions of Delphi to XE5?
While we are considering to upgrade our Delphi 7 applications to Delphi XE5, we have some doubt which are holding our back. Our main concern is how much effort to migrate from BDE to FireDac. We believe many other Delphi users have these questions too. BDE to Firedac migration Question 1. We have about 2 millions lines of codes in more than 800 forms and data modules. Is it possible to convert the entire project (BDE, D7 to FireDac,XE5) in one shot or file by file? 2. The migration Step 7 mentions the following:- >Step 7 >FireDAC does not support desktop DBs, like Paradox...

Cannot find trial downloads of earlier Delphi versions
Hi everyone I was recently asked to help with modifying software that was written in Delphi 6 or 7, I'm not certain which version. I searched the web for a trial that I could download so that I could see whether it would be worth my while buying a full version, but those that I did find require a serial number. Also, Delphi 8 is of no use because the software in question runs on Windows XP. Does anyone know where I might find a trial version of Delphi 6 or 7? I would prefer not to download anything that is cracked. Thanks. There are no older Delphi trails as far as I know. The...

Best practice when code should still compile with elder versions of Delphi but also Delphi 2009
When tryung to compile Turbopower Orpheus and other Turbopower products which I still use in my applications and therefor need to convert to Delphi 2009, I get lots of warnings even though others has made it possible to get Orpheus compiled. The problem is checking a char in a set which gives a type cast warning and suggests using a new function instead. [DCC Warning] ovcdbnum.pas(401): W1050 WideChar reduced to byte char in set expressions. Consider using 'CharInSet' function in 'SysUtils' unit. So what would be the best practice here eg. correcting this ro...

SEPA components for Delphi with Source Code (Delphi 5
Hi all, in the european union change next year the Bankingformat to the SEPA Format. All peoples and companies must change the bankingssoftware and the costumer data form acountnummers in the new IBAN and BIC numbers. See: http://www.arma-it.de/shop/artikelueber.php?wgruppeid=211&wgruppe_offen=211 Functions: - generate SEPA XML'S - Calc IBAN - BIC Database (DE,AT and CH) Questions: vertrieb@arma-it.de PS: Bankinssoftware for Develpoers (Germany only) http://www.arma-it.de/shop/artikelueber.php?wgruppeid=212&wgruppe_offen=212 El 26/10/13 21:38, A...

Delphi 7 to Delphi XE
Have been using Delphi 7 for many moons ( have got later versions but never upgraded to ) My first problem is: Component Palette. in XE it is a small toolbar docked in top right in Delphi 7 it gives a large view of all the components. I am struggling to be able to cope/access my components.in Delphi XE. Can I make the component pallette tool bar the same size as Delphi 7, or is there a fast way to view/choose all available components in XE, that I have not spotted yet? Kind Regards, Robert. Hi, What I know is that in Delphi 2010 and XE you can choose between t...

Delphi Versions
Don't laugh, but I am not a company and years ago I purchased Delphi 5 professional out of my own pocket, along with Crystal reports developer, Infopower and Orpheus components, help & manual help writer, etc... I am currently writing a program that I would like to market - not complex, single user, non server based. I'm taking a shot on my own without a company to hold my hand. I just want to know if there are any major concerns with continuing with this version of Delphi for the time being? Money is an issue in that I just don't have enough to upgrade all th...

Delphi 4 to Delphi 2007
Hello, I will have to port a D4 application (with source) to D2007. what kind of problem could I face ? I will have to go to customer site tommorow to analyse its source code to quote the work, what should I care of to hestimate the porting time ? Thanks John Terry wrote: > Hello, > I will have to port a D4 application (with source) to D2007. > what kind of problem could I face ? > I will have to go to customer site tommorow to analyse its source code > to quote the work, what should I care of to hestimate the porting time ? You can probably do it by just changi...

Delphi versions
Is Delphi 2007 the last version of Delphi that defaults the String type to AnsiString? Is it still available from Embarcadero? I have a whole lot of projects that use the String type and I have been compiling them in Delphi 7. Pier "Pier Nardin" <piern@ramm.co.za> wrote in message news:590487@forums.embarcadero.com... > Is Delphi 2007 the last version of Delphi that defaults the String type to > AnsiString? Is it still available from Embarcadero? I have a whole lot of > projects that use the String type and I have been compiling them in Delphi > ...

Delphi XE5 first (negative) impression and access to earlier versions?
Hello, I've upgraded to XE5 (from D2010). The motivation was mainly the 64-bit compiler and SVN integration. I don't do mobile development. The first impression is not really that positive: 1) Opening a simple test application results in some sort of stack overflow exception in the IDE. Occurs randomly, thus annoying. 2) Haven't been able to use SVN integration with my local SVN 1.8 workspace. Haven't tried the 64-bit compiler yet. So I thought I'm gonna try with an earlier version, especially for 1) and that I'm having XE4 support for all my used ...

Web resources about - Weak interface references in earlier versions of Delphi - embarcadero.delphi.oodesign

Wikipedia talk:Reference desk/Guidelines/Medical advice - Wikipedia, the free encyclopedia
I disagree with this implication that this section of the guideline represents the consensus. If you look at the last few years of discussion ...

New York Times Removes Reference to President Obama and Cable News
... — Noah Rothman (@NoahCRothman) December 18, 2015 The Times story was published Thursday, but by Friday morning, the reference to cable news ...

Reference Pricing tweak for Medicaid
Reference pricing is a common payment reform for commercial insurance. Common, non-urgent, deferrable procedures are prime candidates. Hip replacement ...

'Enough with the Viagra references,' says the CEO behind the first FDA approved drug to boost women's ...
... the Fortune Most Powerful Women Next Gen conference. But the reaction to the pill still confounded her. "Enough already with the Viagra references," ...

Zootopia Trailer Adds a Godfather Reference to Disney Film - Collider
Watch a new trailer for the Disney animated movie Zootopia, which takes place in a world inhabited by talking animals and features Jason Bateman ...

Hillary Clinton Ends Democratic Debate With A Star Wars Reference
The other day, President Obama ended his White House press conference with a reference to The [...]

Review: Klipsch X20i Reference In-Ear Headphones
These Klipsch X20i Reference In-Ear Headphones are pretty darn fantastic, and worth every penny.`

Kentucky Grade School Scrubs All References To Christianity In ‘Charlie Brown Christmas’
Kentucky Grade School Scrubs All References To Christianity In ‘Charlie Brown Christmas’

Disney Inundates General Hospital Episode With References To New Year's Eve College Football Playoff ...
ESPN says it isn’t worried about viewership for tomorrow’s college football playoff games on New Year’s Eve , but the degree to which TV viewers ...

Go Bang House by Takeru Shoji Architects references traditional Japanese farmhouses
A patio-like corridor surrounds the ground-floor rooms of this house by Takeru Shoji Architects, replicating traditional space in Japanese farmhouses ...

Resources last updated: 1/5/2016 9:20:53 PM