Delphi 7 - 何时使用.create(应用程序)以及何时使用.create(nil)?

Cri*_*ein 1 delphi memory-leaks memory-management

我最近读到了很多关于此的内容,但从未找到最终答案.
所以,例如,如果我写:

Form1 := TForm1.Create(Application);

应用程序应该负责从存储器中释放表单吗?
为什么人们通常做如下:

Form1 := TForm1.Create(Application);
Form1.ShowModal;
Form1.Free; 
Run Code Online (Sandbox Code Playgroud)

??
在某些地方看到,如果你试图"释放"已经被释放的对象,你将得到一个EAccessviolation消息,但是在我测试时并不总是如此.

那么请,这实际上是如何工作的?
这个EAccessviolation让我疯狂,我怎么能完全理解这件事?我在哪里可以找到这些宝贵的信息!??

Ken*_*ite 11

一般规则是:

  • 如果您要自己释放它,请nil作为所有者使用.
  • 如果您不打算自行释放,请指定一位负责释放它的所有者.

所以,如果您的代码是这样的:

Form1 := TForm1.Create(...)
Form1.ShowModal;
Form1.Free;
Run Code Online (Sandbox Code Playgroud)

您应该将其nil作为所有者编写,并在try..finally块中保护它:

procedure TForm1.Button1Click(Sender: TObject);
var
  AForm: TForm2;
begin
  AForm := TForm2.Create(nil);
  try
    AForm.ShowModal;
  finally
    AForm.Free;  // You know when it will be free'd, so no owner needed
  end;
end;
Run Code Online (Sandbox Code Playgroud)

另一方面,如果你要将它放置一段时间,请指定一个可以在以后解决它的所有者:

procedure TForm1.Button1Click(Sender: TObject);
var
  AForm: TForm2;
begin
  AForm := TForm2.Create(Application);
  // Here you don't know when it will be free'd, so let the
  // Application do so
  AForm.Show;
end;
Run Code Online (Sandbox Code Playgroud)

如果按照我在此处演示的方式完成,这些技术都不会导致访问冲突.请注意,在这两种情况下,我都没有使用IDE生成的Form2变量,而是使用本地变量来避免混淆.那些IDE生成的变量是邪恶的(除了Form1你所命名的或代表主要形式的任何名称,它必须由应用程序自动创建和拥有).除了主窗体的var之外,我总是立即删除该自动生成的变量,并且永远不会自动创建除数据模块之外的任何东西(可以在主窗体之前自动处理没有任何问题,因为数据模块不能是主窗体).

  • 在内存管理的上下文中,使用Application作为所有者是没有意义的.所有者在被销毁时释放所拥有的对象,并且因为当程序退出时,Application对象将被销毁,因为你仍然有内存泄漏.当程序退出时,所有内存都将被释放,因此使用Application作为所有者并没有什么不同. (2认同)