Is there any way to know if a object is being created or destroyed inside a class helper?
Asked Answered
D

3

5

I have few class helpers for components to create sub-components, like popup menus, to access this sub-components in run time, I create a Singleton TDictionary.

My question is how do I know that the owner-component is being destroyed to remove the sub-component from the TDictionary?

If it is a specialized component I add it in the destructor, but I cannot add constructor and/or destructor in the class helper.

Edit - Solution

I created a base object that accepts TObject as parameters, when used, the remove action must be done manually.

Then I inherited a new class from it, override the methods to accept only TComponent. This is how the relevant part of the code is now:

type     
  TCustomLinkedComponents = class(TCustomLinkedObjects)
  strict private
    type
      TCollector = class(TComponent)
      protected
        procedure Notification(AComponent: TComponent; Operation: TOperation); override;
      end;
  strict private
    FCollector: TCollector;
[..]
  end;

procedure TCustomLinkedComponents.Add(Owner: TComponent; const LinkedName: string; LinkedComponent: TComponent);
begin
  inherited Add(Owner, LinkedName, LinkedComponent);
  FCollector.FreeNotification(LinkedComponent);
end;

procedure TCustomLinkedComponents.TCollector.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if Operation = opRemove then
    LinkedObjects.Remove(TObject(AComponent));
end;

Using this approach I can resolve my actual need and let opened to be easily extented latter.

Dibbrun answered 1/8, 2012 at 18:42 Comment(0)
G
5

Instead of a TDictionary, make a custom TComponent descendant that contains a TDictionary. Then look into how TComponent.FreeNotification works, and the solution should become obvious. :)

Gorgeous answered 1/8, 2012 at 18:53 Comment(3)
Hi Mason, it will work for components, but I want something more generic to use with TObjects.Dibbrun
@Cesar: Then you're out of luck. There's no way to tell "if an object is being created or destroyed inside a class helper," and your code shouldn't have to know that. What it does need to know is who holds a reference to what, so it can clean things up properly. If you can't use the TComponent notification system, you have to implement something like it yourself.Gorgeous
You could hook TObject.FreeInstance to make it work for any object.Bade
A
2

If you want to know if the component is being destroyed, you should use

function IsBeingDestroyed(AComponent : TComponent) : Boolean;
begin
  Result := csDetroying in AComponent.ComponentState;
end;

If you want to be notified when it is being destroyed, using FreeNotification is the way to go.

For a little more detail on FreeNotification, you can check this post.

Abaddon answered 1/8, 2012 at 19:6 Comment(5)
But TDictionary is not a component.Langsdon
Hi Ken, see my comment to Mason, I want it working for TObject.Dibbrun
@TLama, And it doesn't need to. It would make thing slightly easier, sure, but not required. It would just require a TComponent instance that goes hand in hand with his TDictionary to manage the FreeNotifications in the same way the TComponentList class works.Abaddon
@Ken, I know, but you forgot to mention in your post, that OP needs to wrap his dictionary into a component.Langsdon
@Cesar, If what you want is possible at all, it would be down the "ugly hack road", and believe me, you don't want to go there. If there was an elegant way to do that with TObject, I doubt they would have re-implemented it in TComponent. (Though anything is possible)Abaddon
T
2

No you can't. Delphi does not keep special track whether or not something is created/destroyed by a class helper.

Transcend answered 1/8, 2012 at 19:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.