Form.Release + NIL

Hol*_*rwa 11 delphi winapi vcl

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

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

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

Form1 := nil;
Run Code Online (Sandbox Code Playgroud)

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

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

小智 17

放线

  Form1 := nil;  
Run Code Online (Sandbox Code Playgroud)

就在发布电话之后.

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


Fra*_*ois 11

发布只是(可能)推迟免费.调用Release后你应该做的第一件事就是修改变量.
然后,即使某些代码在实际销毁之前尝试引用Form1,您也会安全.在您的代码中的情况下,它将安全地为新用法重新创建另一个Form1,而不会打扰被销毁的那个.


Jim*_*eth 5

你可以总是这样称呼:

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;
Run Code Online (Sandbox Code Playgroud)

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