在 Delphi 中为表单分发与其生命周期相关的接口对象的安全方式? [英] Safe way in Delphi for a Form to distribute interface objects tied to its lifetime?
问题描述
我有一个 Delphi 表单,它提供接口对象背后的功能,代码的其他部分也通过属于表单的属性获取引用.我无法将界面功能委托给子对象,因为该功能中有太多是由表单上的控件/组件提供的.我不能使用 TAggregatedObject 或 TContainedObject 来链接传递给 Form 的接口对象的生命周期,因为 TForm 类不是从 TinterfacedObject 继承的,而且 Delphi 不支持多重继承,所以我不能将 TInterfacedObject 混合到继承链中.如果某个 Form 被销毁,而其他一些代码持有 Form 传递的接口引用之一,则这种情况可能会导致访问冲突.谁能想出一个好的解决办法来解决这个问题?
I have a Delphi Form that provides the functionality behind an interface object that other parts of the code get references too via a property belonging to the Form. I can't delegate the interface functionality to a child object because too much of that functionality is serviced by controls/components on the form. I can't use TAggregatedObject or TContainedObject to link the lifetime of the interfaced objects being passed around to the Form because the TForm class does not inherit from TinterfacedObject and Delphi does not support multiple inheritance so I can't mix in TInterfacedObject into the inheritance chain. This situation can lead to access violations if a Form gets destroyed while some other code holds one of the interface references passed out by the Form. Can anyone think of a good solution to this problem?
推荐答案
您可以将接口委托给子对象,只需让该对象包含一个指向 Form 的内部指针,这样它就可以在需要时访问 Form 的控件,没有什么不同那么你现在已经在做.
You can delegate the interface to a child object, just have that object contain an internal pointer to the Form so it can access the Form's controls when needed, no different then you are already doing right now.
您可以根据需要使用 TAggregateObject
或 TContainedObject
.它们不需要从 TInterfacedObject
派生的 Form.它们只需要一个 IInterface
接口指针,TComponent
派生自 IInterface
(并覆盖 _AddRef()
和 _Release()
禁用引用计数),因此您可以将表单本身(作为 TComponent
后代)作为所需的 IInterface
指针传递.
You can use TAggregateObject
or TContainedObject
for your needs. They do not require the Form to derive from TInterfacedObject
. All they do require is an IInterface
interface pointer, and TComponent
derives from IInterface
(and overrides the _AddRef()
and _Release()
to disable reference counting), so you can pass the Form itself (being a TComponent
descendant) as the required IInterface
pointer.
剩下的唯一问题是表单关闭,而其他代码持有活动接口引用.最简单的解决方案是 1) 重写该代码以在关闭表单时不保留这些引用,或者 2) 在这些引用被释放之前不允许关闭表单.
That leaves the only issue remaining - the Form closing while active interface references are being held by other code. The simpliest solution is to either 1) rewrite that code to not hold on to those references while the Form is closing, or 2) don't allow the Form to close until those references have been released.
这篇关于在 Delphi 中为表单分发与其生命周期相关的接口对象的安全方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!