Dan*_*rić 8 delphi implementation interface reference-counting
我有一个助手类,将在整个应用程序中广泛使用.实现依赖于接口引用计数,这个想法大致是:
...
var
lHelper: IMyHelper;
begin
lHelper := TMyHelper.Create(some params);
...some code that doesn't have to access lHelper
end;
Run Code Online (Sandbox Code Playgroud)
因此,实现依赖于IMyHelper在方法结束时超出范围,但之前没有.
所以我要问的是,我可以肯定,在未来的某些Delphi编译器中,如果在该方法的其余部分中没有访问该变量,那么在创建它之后就不会发挥智能并立即释放界面吗?
Arn*_*hez 10
恕我直言,你可以对此充满信心.超出范围的模式可能对该方法的指令块保持全局.这将是一个突破性的变化.
请参阅Barry Kelly的评论(来自Embarcadero):
关于你之前的评论,关于显式变量:在我们优化接口变量使用的假设(和突破性变化)情况下,我们不仅可能打破所描述的类似RAII的功能,而且还可以打破显式变量方法; 不使用分配给FooNotifier和BarNotifier的值,因此"理论上"它们可以更快地释放,甚至可能重用相同的存储.
但是,当然,界面的破坏可能会产生副作用,而这正是帖子中效果所依赖的.改变语言使得像这样的副作用有明显的变化并不是我们自愿做的事情.
所以你可以猜测Embarcadero不会在这里引入任何向后兼容性变化.重用接口内存的好处不值得打破兼容性并引入副作用:保存指针(4或8字节)现在不值得,特别是当堆栈已经分配和对齐时(x64模型使用)堆栈多于x86).
只有当垃圾收集器被引入到语言中时(从我个人的角度来看,我不想要),对象的生命周期才会发生变化.但在这种情况下,寿命可能会更长.
在所有情况下,您都可以创建自己的代码,以确保它将在方法结束时发布:
var
lHelper: IMyHelper;
begin
lHelper := TMyHelper.Create(some params);
try
...some code that doesn't have to access lHelper
finally
lHelper := nil; // release the interface count by yourself
end;
end;
Run Code Online (Sandbox Code Playgroud)
实际上,这是编译器已经生成的代码.写这个将是完全多余的,但它将确保编译器不会欺骗你.
在谈到接口和引用计数时,请考虑Delphi中循环引用的潜在问题.请参阅这篇伟大的文章(即"例2-15"),了解接口循环引用的"弱指针"的必要性.
其他语言(如Java或C#)使用垃圾收集器来解决此问题.Objective C使用一个明确的"归零弱指针"机制来解决它 - 参见本讨论或这个SO答案的潜在实现.也许Delphi的未来版本可能会考虑使用类似于Objective C中引入的ARC模型的实现.但我怀疑会有一个明确的语法来保持与现有代码的兼容性.