我以前从未真正听说FreeOnRelease
过。一个快速的谷歌搜索出现了原因。 来自官方文档:
FreeOnRelease 在组件实现的接口被释放时调用。FreeOnRelease 内部使用,调用对应的接口方法。不需要直接调用 FreeOnRelease。
至于Free
vs. Destroy
,Free
是一个安全功能。它基本上实现为if self <> nil then self.Destroy;
,它的创建是为了使构造函数和析构函数可以安全使用。这是基本思想:
如果您正在构造一个对象并且引发了未处理的异常,则将调用析构函数。如果您的对象包含其他对象,则在错误发生时它们可能已创建,也可能尚未创建,因此您不能只尝试调用Destroy
所有对象。但是您需要一种方法来确保已创建的那些确实会被销毁。
由于 Delphi 在调用构造函数之前将对象的地址空间清零,因此此时任何尚未创建的内容都保证为零。因此,您可以if FSubObject <> nil then FSubObject.Destroy
一遍又一遍地为所有子对象说,(如果您忘记了您将遇到访问冲突),或者您可以使用该Free
方法,它会为您完成。(这是对 C++ 的巨大改进,在调用构造函数之前内存空间不会归零,这需要您将所有子对象包装在智能指针中并使用 RAII 来维护异常安全!)
它在其他地方也很有用,而且真的没有理由不使用它。我从来没有注意到这会Free
带来任何可衡量的性能损失,并且可以提高代码的安全性,因此在所有情况下都使用它是个好主意。
话虽如此,在具体处理表单时,还有一个额外的变量需要考虑:Windows 消息队列。您不知道要释放的表单是否仍有待处理的消息,因此调用Free
表单并不总是安全的。为此,有Release
方法。它将一条消息发布到队列中,导致表单在没有更多消息要处理时自行释放,因此它通常是释放不再需要的表单的最佳方式。