11

如果在使用表单后调用 Form.Release,它将释放所有相关内存但不会将表单变量设置为 nil。

if not assigned (Form1) then
  begin
    Application.CreateForm(Tform1, Form1);
    try
      // Do something
    finally
      Form1.Release
    end;
  end;

为了能够再次调用相同的代码,Form1 必须在某个时候设置为 nil。从 Release 我不能做的描述

Form1 := nil;

在 Release 之后,因为 Release 过程将在被调用之后和实际释放表单之前直接返回。我无法检测到 Form.Release 何时完成将表单 var 设置为 nil。

做这个的最好方式是什么?

4

5 回答 5

17

放线

  Form1 := nil;  

就在调用 Release 之后。

Release 只是将 CM_RELEASE 消息发布到 Form,它允许 Form 在处理 CM_RELEASE 消息之前完成其队列(事件处理程序)中的内容,这意味着通常只是调用 Free。
因此,在调用 Release 之后,您不应假定 Form 变量仍然指向有效的 Form,从而将 nil 放入变量中。

于 2008-11-08T09:12:50.450 回答
11

发布只是(可能)延迟的免费。调用 Release 后您应该做的第一件事是取消变量。
然后,即使某些代码在实际销毁 Form1 之前尝试引用它,您也将是安全的。在像您的代码中这样的情况下,它只会安全地重新创建另一个 Form1 以供新用途,而不会打扰被销毁的那个。

于 2008-11-08T09:22:22.427 回答
4

你们可以总是这样称呼:

procedure FreeOrReleaseAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  if Temp is TCustomForm then
    TCustomForm(Temp).Release
  else
    Temp.Free;
end;

请务必在转换为 TObject 后检查类型,因为您无法测试 Obj 的类型。这应该是安全的,因为与 Free 一样,Release 是非虚拟的。

于 2008-11-08T19:58:43.563 回答
2

如前所述,如果要关闭/释放自身,Release 只是表单使用的延迟释放。其他然后被推迟它与发布没有什么不同。所以在那个例子中调用 Release 是没有用的。调用 Free 似乎更合乎逻辑。您可以在调用 Free 或使用 FreeAndNil 后将其设置为 nil。

如果您仍想使用 Release,那很好。只需将变量值设置为 nil 即可。这样做不会使论坛的行为有所不同。但请记住,在这种情况下,调用 Free 而不是 Release 会更有效且更具确定性。我的偏好是只在真正需要的地方使用 Release。

于 2008-11-08T13:47:24.453 回答
0

在 Delphi Win32 中,释放对象的适当方法是调用

FreeAndNil(Form1)

这在一次调用中完成了这两项工作。

但是,我有一种偷偷摸摸的感觉,你的问题比表面上看到的要多。您是否使用 Delphi for .NET - 如果是,是哪个版本?

于 2008-11-08T08:53:05.497 回答