我有一个项目,其中多个单位具有初始化部分。我想控制执行此块的顺序。
根据以下question,这是基于单位编制的顺序,因此最终订单应基于源DPR的使用条款中的单位排列。
以下是我项目的DPR来源:
program X;
uses
Vcl.Forms,
uMain in 'uMain.pas' {MainForm},
uFooA in 'uFooA.pas',
uFooB in 'uFooB.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
我的问题是,这根本不是执行初始化块的顺序。
How it should be | How it actually is
|
1. uMain | 1.uFooA
2. uFooA | 2.uFooB
3. uFooB | 3.uMain
我很想提供一个SSCCE,但我无法在一个新项目上重新制作这个问题。
我尝试重建项目但没有成功。
我错过了什么?
答案 0 :(得分:5)
即使编译器确定初始化有严格的方法,但是当有许多具有许多依赖性的单元时,人类很难准确地找出并控制它。
E.g。您的DPR可能会使用UnitA, UnitB, UnitC;
,但如果UnitA
依赖于UnitB
,则必须首先初始化UnitB。
不可否认,具有初始化和终结部分的单元的功能可以使添加功能像“添加单元”一样简单。虽然这看起来很棒,但实际上,在很大的项目中它往往会妨碍它。我个人认为这个“特征”非常可怕。
控制单位的inialisation序列的最佳和最可靠的方法是明确地这样做。 E.g。
program X;
uses
Vcl.Forms,
uMain in 'uMain.pas' {MainForm},
uFooA in 'uFooA.pas',
uFooB in 'uFooB.pas';
{$R *.res}
begin
Init_uMain;
Init_uFooA;
Init_uFooB;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
Finalise_uFooB;
Finalise_uFooA;
Finalise_uMain;
end.
显然上面的代码缺少适当的try..finallys,并且会因许多需要初始化的单元而变得混乱。但是,还可以应用其他技术来保持可管理性。