Delphi表单组件销毁命令的控制

Delphi表单组件销毁命令的控制,delphi,Delphi,有没有办法控制Delphi表单销毁其组件的顺序 我在表单销毁时得到了AVs,因为它在另一个访问第一个组件的组件之前销毁了一个组件 目前,我没有办法避免AVs,除了在终结部分释放第一个组件您必须对引用的控件调用FreeNotification(),并覆盖引用它的控件的受保护的Notification()方法 假设您有一个链接到另一个组件的属性(例如,TEdit): 然后,如果您的属性设置为链接到这样的组件,您可以通过调用其FreeNotification()方法告诉它您希望在释放该组件时收到通知:

有没有办法控制Delphi表单销毁其组件的顺序

我在表单销毁时得到了AVs,因为它在另一个访问第一个组件的组件之前销毁了一个组件


目前,我没有办法避免AVs,除了在终结部分释放第一个组件

您必须对引用的控件调用
FreeNotification()
,并覆盖引用它的控件的受保护的
Notification()
方法

假设您有一个链接到另一个组件的属性(例如,
TEdit
):

然后,如果您的属性设置为链接到这样的组件,您可以通过调用其
FreeNotification()
方法告诉它您希望在释放该组件时收到通知:

procedure TMyControl.SetEdit(Value: TEdit);
begin
  if FEdit <> Value then
  begin
    if FEdit <> nil then
      FEdit.RemoveFreeNotification(Self); 
    FEdit := Value;
    if FEdit <> nil then
      FEdit.FreeNotification(Self); 
  end;
end;
这样,您将知道何时可以访问
TEdit
组件,何时不再访问。如果
FEdit
nil
,则不应访问它

举例如下:

文件:

您必须对引用的控件调用
FreeNotification()
,并重写引用它的控件的受保护
notification()
方法

假设您有一个链接到另一个组件的属性(例如,
TEdit
):

然后,如果您的属性设置为链接到这样的组件,您可以通过调用其
FreeNotification()
方法告诉它您希望在释放该组件时收到通知:

procedure TMyControl.SetEdit(Value: TEdit);
begin
  if FEdit <> Value then
  begin
    if FEdit <> nil then
      FEdit.RemoveFreeNotification(Self); 
    FEdit := Value;
    if FEdit <> nil then
      FEdit.FreeNotification(Self); 
  end;
end;
这样,您将知道何时可以访问
TEdit
组件,何时不再访问。如果
FEdit
nil
,则不应访问它

举例如下:

文件:

我做了一些搜索和测试,找到了如何控制Delphi表单组件销毁顺序

设计时和运行时有两种方法:

  • 在设计时,编辑表单的DFM,将第一个组件的对象块作为第一个块移动到必须在第一个块之后释放的任何其他组件的任何其他对象块之前

  • 在运行时,在表单OnCreate中,将第一个组件的ComponentIndex属性更改为低于依赖它的其他组件的任何值,例如0,这将使它成为最后一个被释放的组件

  • 示例:
    FirstComp.ComponentIndex:=0

    就这样

    正如您所看到的,Delphi按照组件添加到表单(LIFO)的相反顺序释放组件,但正如我所解释的,我们可以改变这个顺序


    谢谢大家的宝贵帮助。非常感谢。

    我做了一些搜索和测试,找到了如何控制Delphi表单组件的销毁顺序

    设计时和运行时有两种方法:

  • 在设计时,编辑表单的DFM,将第一个组件的对象块作为第一个块移动到必须在第一个块之后释放的任何其他组件的任何其他对象块之前

  • 在运行时,在表单OnCreate中,将第一个组件的ComponentIndex属性更改为低于依赖它的其他组件的任何值,例如0,这将使它成为最后一个被释放的组件

  • 示例:
    FirstComp.ComponentIndex:=0

    就这样

    正如您所看到的,Delphi按照组件添加到表单(LIFO)的相反顺序释放组件,但正如我所解释的,我们可以改变这个顺序


    谢谢大家的宝贵帮助。非常感谢。

    您需要将您的组件修复到他们不关心的位置。此外,我不明白为什么
    定稿
    是相关的。即模块终止时。但当表单被销毁时,问题就出现了。后者通常是由前者触发的,但并不总是。谢谢你的帮助。即使在销毁时,第二个组件也需要从第一个组件读取/写入数据,因此第一个组件必须在那里,并作为最后一个组件释放。定稿部分在表单ObDestroy之后执行,所以我在那里销毁了第一个组件。我认为期望控制销毁顺序是不现实的。相反,你应该要求得到销毁通知。你所希望的打破了组件的设计规则。我找到了一种控制破坏顺序的方法,请参见下面的答案。在某些情况下,你找到了一种控制破坏顺序的方法。不确定这是否是通用的,它肯定依赖于内部。这可以由供应商更改。而是确保在释放合作伙伴控件时收到通知,之后不再访问它。这样更安全。您需要修复组件,使其不关心此问题。此外,我不明白为什么
    定稿
    是相关的。即模块终止时。但当表单被销毁时,问题就出现了。后者通常是由前者触发的,但并不总是。谢谢你的帮助。即使在销毁时,第二个组件也需要从第一个组件读取/写入数据,因此第一个组件必须在那里,并作为最后一个组件释放。定稿部分在表单ObDestroy之后执行,所以我在那里销毁了第一个组件。我认为期望控制销毁顺序是不现实的。相反,你应该要求得到销毁通知。你所希望的打破了组件的设计规则。我找到了一种控制破坏顺序的方法,请参见下面的答案。在某些情况下,你找到了一种控制破坏顺序的方法。不确定这是否是通用的,它肯定依赖于内部。这可以由供应商更改。而是确保在释放合作伙伴控件时收到通知,之后不再访问它。这样更安全。@Remy感谢您的更正(删除已存在链接组件上的免费通知)。@Remy感谢您的更正(删除已存在链接组件上的免费通知)
    protected
      procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    ...
    
    procedure TMyControl.Notification(AComponent: TComponent; Operation: TOperation);
    begin
      inherited Notification(AComponent, Operation);
      if (Operation = opRemove) and (AComponent = FEdit) then
        FEdit := nil;
    end;