在 Delphi 中,将 owner 设置为 Application 而不是 nil 有什么好处?

in Delphi, what is the benefit of setting owner as Application instead of nil?

"Application" 是 VCL 的一部分,因此不是线程安全的(可能维护它拥有的非线程安全组件列表)。

我正在处理的项目有几个实例,其中 Application 被设置为 Owner,Self 不是一个选项(class 方法)。 我想传递 "nil" ,因为变量在这个函数结束时被释放了。

假设有人忘记释放应用程序拥有的变量:

当应用程序关闭时,内存被释放。 但我也读到 Windows 跟踪分配给每个进程的内存。所以,理论上,如果一个 nil-owned 变量没有被释放,Windows 会在应用程序/进程终止时释放它。

那么,将所有者设置为 Application 而不是 Nil 有什么好处?

以下问题讨论了释放 nil 拥有的变量的责任,但到此为止:

What is the meaning of nil owner in component constructor

虽然系统确实会在进程终止时释放内存,但执行期间的泄漏是一个潜在的问题。如果一个程序执行重复的操作,并且每次都泄漏内存,那么这些泄漏会随着时间的推移而累积并最终导致内存不足的情况。

对于应用程序单例对象拥有的组件,可以看到相同的行为。如果它们没有被显式销毁,那么只有在应用程序终止时它们才会被销毁。同样,随着流程的执行,这些泄漏可能会随着时间的推移而累积。

检测泄漏的正常方法是在执行期间跟踪所有分配,然后,作为进程终止的最后行为,检查所有分配是否都有匹配的释放。此功能由各种工具提供,但在 Delphi 上下文中,FastMM 内存管理器是提供此功能的最常用工具。

如果您创建了一个由应用程序对象拥有的组件,并且没有明确销毁它,那么当您的泄漏检查器执行时,它不会显示为已泄漏。这是不可取的,因为您有未检测到的真正泄漏。

这个论点得出的结论是,在您描述的场景中最好有无主组件。

不利的一面是,有时您会创建希望与应用程序对象一样长的组件,并且可能很难在代码中找到一个好的位置来显式销毁它们。在这种情况下,由应用程序对象拥有是一个好方法。这正是所有者机制的设计目的。

我的经验法则:

  1. 如果组件是由流系统创建的(即表单),它将使用所有权机制来确保正确的生命周期管理。您在代码中无事可做。
  2. 如果您在代码中显式创建组件,那么最好遵循正常的创建模式并在代码中显式销毁它。在这种情况下,使组件成为无主。
  3. 如果您不容易找到销毁组件的好地方,并且可以将其生命周期绑定到另一个组件(即应用程序),则将该组件作为所有者传递。

回到你问的问题。您询问了将应用程序对象用作所有者的优势的原因。如上所述,在许多情况下,不拥有这些组件实际上是有利的。但有时将应用程序对象作为所有者是有利的。

总而言之,没有一个硬性规则可以遵循。您需要了解所有权的含义,然后为每个组件选择合适的所有者,这可能因情况而异。