【问题标题】:How can I detect that a component has been freed?如何检测组件已被释放?
【发布时间】:2012-09-12 01:23:10
【问题描述】:

我创建了一个组件,然后将我的主窗体上的面板传递给它。

这是一个非常简单的例子:

procedure TMy_Socket.StatusPanel_Add(AStatusPanel: TPanel);

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

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

如果面板已被释放,我如何在组件中检测到我知道我无法引用它?

我试过if (AStatusPanel = nil),但不是nil,它还有一个地址。

【问题讨论】:

    标签: delphi


    【解决方案1】:

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

    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

    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; 
    

    【讨论】:

      【解决方案2】:

      如果在释放另一个组件时需要通知您的组件,请查看TComponent.FreeNotification。它应该正是您所需要的。

      【讨论】:

      • @Steve:您将 Notification proc 放在您的 TMy_Socket 类上。查看文档页面底部的示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 2022-08-16
      相关资源
      最近更新 更多