我有两个单元unitA和unitB。类TFoo在unitB中声明。
在unitA的终结过程中调用B.Free总是安全的吗?
它如何依赖于unitA和unitB在dpr中的顺序?
在执行unitA finalization时,我可以确保unitB存在吗?
unit unitB;
interface
type
TFoo = class
// code...
end;
// code....
end;
unit unitA;
// code..
implementation
uses
unitB;
var
A: TStringList;
B: UnitB.TFoo;
initialization
A:= TStringList.Create;
B:= UnitB.TFoo.Create;
finalization
A.Free;
B.Free; // Is it safe to call?
end.发布于 2010-02-20 15:26:08
可以,因为B是在单元A中创建的。规则是根据初始化部分在DPR中的顺序调用它们,除非其中一个单元引用了另一个单元。在这种情况下,首先初始化引用的单元。最终完成的顺序是相反的。
在您的案例中,单元B没有初始化部分,因此它是一个无意义的点。但是,在执行单元A初始化部分时,它将使用单元B中的TFoo定义。
关于初始化和结束部分的另一个警告-它们发生在全局异常处理程序之外。那里发生的任何异常都会终止应用程序。因此,在大型程序中,跟踪和调试这些异常可能是一件痛苦的事情。你可以考虑在那里使用你自己的异常日志,只是为了确保。
发布于 2010-02-20 18:42:27
no。你可以尝试,你可以希望,但不能保证在调用初始化和结束的顺序。参见qc72245、qc56034和many more。
更新:
示例:
unitA // no dependency on unitB
var SomeController;
initialization
SomeController := TSomeController.Create;
finalization
SomeController.Free;
unitB
uses
unitA;
initialization
SomeController.AddComponent(UnitBClass);
finalization
SomeController.RemoveComponent(UnitBClass);常用(正确)调用顺序(99.99%):
但有时Delphi会编译错误的文件:
离题的小故事:
我们有一个相当大的项目,Type1在Unit1中,Type2 = class(Type1)在Unit2中。文件按project.dpr排序,几年后添加Unit200 (与Unit1/2无关) Delphi在Unit2开始编译项目,在Unit1初始化之前初始化。唯一安全的解决方案是从初始化节调用您自己的Init函数。
发布于 2010-02-20 15:12:43
据我所知,你所得到的应该是完全有效的。有点笨拙,但很有道理。
但更好的方法可能是在单元B中声明一个变量,并让B初始化/终止它。由于初始化发生在调用任何其他代码之前,因此只要在单元A的uses子句中声明它,它就会在单元A可用之前被初始化。
您可能想要考虑的另一个步骤是进一步将B的单位变量作为按需加载的函数调用,但这也可能取决于您的用法。
例如
unit unitB;
interface
type
TFoo = class
// code...
end;
// code....
function UnitVarB:TFoo;
implementation
var
gUnitVarB : TFoo;
function UnitVarB:TFoo
begin
if not assigned(gUnitVarB) then
gUnitVarB := TFoo.Create;
result := gUnitVarB;
end;
finalization
if assigned(gUnitVarB) then
gUnitVarB.free; //or FreeAndNil(gUnitVarB);
end;
unit unitA;
// code..
implementation
uses
unitB;
var
A: TStringList;
//code...
...UnitVarB....
//code...
initialization
A:= TStringList.Create;
finalization
A.Free;
end.我似乎记得单元初始化可能是昂贵的,因为在编译期间,如果您不再直接引用的单元仍然在uses子句中,则智能链接器不会因为初始化部分而删除它。虽然这听起来可能不是那么糟糕,如果每个单元都有一个初始化部分,那么大多数Delphi程序将比它们已经大得多。
我并不是说不要使用它们,但我的经验法则是谨慎使用它们。
您的初始代码示例违反了这一规则。我想我应该提一下。
瑞安
https://stackoverflow.com/questions/2301355
复制相似问题