德尔福:由于当接口引用不再在同块月底发布?
-
22-07-2019 - |
题
我最近绊倒造成一些很老的代码,我写了明显假设在with
语句中使用该接口引用的问题将尽快with
块被释放左键 - 有点像一个隐含的try-finally
块(类似的C#using
语句如果我理解正确的)。
显然(在2009年的Delphi)这不是(不再?)的情况。有谁知道什么时候会发生?或者是我的代码只是简单的错误,开始用?
要阐明,这里是一个简化的例子:
type
IMyIntf = interface;
TSomeObject = class(TInterfacedObject, IMyIntf)
protected
constructor Create; override; // creates some sort of context
destructor Destroy; override; // cleans up the context created in Create
public
class function GetMyIntf: IMyIntf; //a factory method, calling the constructor
end;
procedure TestIt;
begin
DoSomething;
with (TSomeObject.GetMyIntf) do
begin
DoStuff;
DoMoreStuff;
end; // <- expected: TSomeObject gets destroyed because its ref.count is decreased to 0
DoSomethingElse;
end; // <- this is where TSomeObject.Destroy actually gets called
每当有人开始老“with
是邪恶的”的说法,这是始终是一个例子,我脑子里想这让我继续走下去“是的,但是......”。好像我错了...任何人都可以证实?
解决方案
在帕斯卡保留字的with
/ Delphi的仅用于容易访问的记录或对象/类成员(即为了不提记录的/对象的/类的名称)。这是从涉及到垃圾回收的C#with
很大的不同。它在Pascal语言已经存在的那一天开始records
出生,简化代码调用许多数据成员(当时简称“田”)。
要总结,with
无关与垃圾收集,内存或对象实例的破坏释放。那些在with
头部构造的对象可能只是一直在一个单独的代码行初始化之前,它是相同的。
其他提示
此WITH-行为从未改变。为了达到你的预期行为,你可以用这种方式更改代码:
procedure TestIt;
var
myIntf: IMyIntf;
begin
DoSomething;
myIntf := TSomeObject.GetMyIntf
DoStuff;
DoMoreStuff;
myIntf := nil; // <- here is where TSomeObject.Destroy called
DoSomethingElse;
end;
,也可以做到这一点在过程:
procedure TestIt;
procedure DoAllStuff;
var
myIntf: IMyIntf;
begin
myIntf := TSomeObject.GetMyIntf
DoStuff;
DoMoreStuff;
end; // <- here is where TSomeObject.Destroy called
begin
DoSomething;
DoAllStuff;
DoSomethingElse;
end;
不隶属于 StackOverflow