如何检测组件已释放? [英] How can I detect that a component has been freed?

查看:66
本文介绍了如何检测组件已释放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个创建的组件,然后将其传递到主窗体上的面板中。

I have a component that I create and then pass into it a panel on my main form.

这里是一个非常简化的示例:

Here is a very simplified example:

procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);

然后该组件将根据需要更新面板标题。

This component will then update the panels caption as the need arises.

在我的主程序中,如果我 FreeAndNil 面板,下一次组件尝试更新面板时,我得到一个AV。我知道为什么:该组件对面板的引用现在指向一个未定义的位置。

In my main program if I FreeAndNil the panel the next time the component tries to update the panel I get an AV. I understand why: the component's reference to the panel now is pointing to an undefined location.

如何在组件内检测面板是否已释放,所以我知道不能引用吗?

How can I detect within the component if the panel has been freed so I know I can not reference it?

我尝试了 if(AStatusPanel = nil),但不是 nil ,它仍然有一个地址。

I tried if (AStatusPanel = nil) but it is not nil, it still has an address.

推荐答案

您必须致电小组的 FreeNotification( )方法,然后让您的 TMy_Socket 组件覆盖虚拟的 Notification()方法,例如(根据您的命名方案,我假设您可以向您的组件中添加多个 TPanel 控件):

You have to call the Panel's FreeNotification() method, and then have your TMy_Socket component override the virtual Notification() method, eg (given your naming scheme, I assume you can add multiple TPanel controls to your component):

type
  TMy_Socket = class(TWhatever)
  ...
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  ...
  public
    procedure StatusPanel_Add(AStatusPanel: TPanel); 
    procedure StatusPanel_Remove(AStatusPanel: TPanel); 
  ...
  end;

procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel); 
begin
  // store AStatusPanel as needed...
  AStatusPanel.FreeNotification(Self);
end;

procedure TMy_Socket.StatusPanel_Remove(AStatusPanel: TPanel); 
begin
  // remove AStatusPanel as needed...
  AStatusPanel.RemoveFreeNotification(Self);
end;

procedure TMy_Socket.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (AComponent is TPanel) and (Operation = opRemove) then
  begin
    // remove TPanel(AComponent) as needed...
  end;
end; 

如果您仅跟踪一个 TPanel 改为时间:

If you are only tracking one TPanel at a time instead:

type
  TMy_Socket = class(TWhatever)
  ...
  protected
    FStatusPanel: TPanel;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  ...
  public
    procedure StatusPanel_Add(AStatusPanel: TPanel); 
  ...
  end;

procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel); 
begin
  if (AStatusPanel <> nil) and (FStatusPanel <> AStatusPanel) then
  begin
    if FStatusPanel <> nil then FStatusPanel.RemoveFreeNotification(Self);
    FStatusPanel := AStatusPanel;
    FStatusPanel.FreeNotification(Self);
  end;
end;

procedure TMy_Socket.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (AComponent = FStatusPanel) and (Operation = opRemove) then
    FStatusPanel := nil;
end; 

这篇关于如何检测组件已释放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆