Zam*_*Zam 5 delphi android firemonkey delphi-xe7 delphi-xe8
在Windows操作系统(7 SP1 x64),MACOSX(10.10.3)和Android(5.0.2)上创建订单:
"class constructor TGlobalClass.Create;" -> "constructor TfmMain.Create;" -> "procedure TfmMain.FormCreate(Sender: TObject);"
Run Code Online (Sandbox Code Playgroud)
Windows操作系统和MACOSX上的下达顺序:
"TfmMain.FormDestroy" -> "destructor TfmMain.Destroy" -> "class destructor TGlobalClass.Destroy;"
Run Code Online (Sandbox Code Playgroud)
Android上的下达订单:
"class destructor TGlobalClass.Destroy;" -> "TfmMain.FormDestroy" -> "destructor TfmMain.Destroy"
Run Code Online (Sandbox Code Playgroud)
问题是:为什么Android平台上的CLASS VAR在主窗体之前发布?
代码示例:
unit uClassVar;
interface
type
TGlobalClass = class
class var F1: Integer;
class constructor Create;
class destructor Destroy;
end;
implementation
{ TX }
class constructor TGlobalClass.Create;
begin
{ Breakpoint there }
F1 := 100;
end;
class destructor TGlobalClass.Destroy;
begin
{ Breakpoint there }
F1 := 200;
end;
end.
Run Code Online (Sandbox Code Playgroud)
主要单位:
unit ufmMain;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics;
type
TfmMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
var
fmMain: TfmMain;
z: Integer;
implementation
uses
uClassVar;
{$R *.fmx}
constructor TfmMain.Create;
begin
{ Breakpoint there }
inherited;
end;
destructor TfmMain.Destroy;
begin
{ Breakpoint there }
inherited;
end;
procedure TfmMain.FormCreate(Sender: TObject);
begin
{ Breakpoint there }
TGlobalClass.F1 := -99999;
end;
procedure TfmMain.FormDestroy(Sender: TObject);
begin
{ Breakpoint there }
z := 200;
end;
end.
Run Code Online (Sandbox Code Playgroud)
项目文件:
program ClassVar;
uses
System.StartUpCopy,
FMX.Forms,
ufmMain in 'ufmMain.pas' {fmMain},
uClassVar in 'uClassVar.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TfmMain, fmMain);
Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)
桌面编译器
当应用程序对象销毁其组件时,您的主窗体将被销毁.这发生在FMX.Forms中DoneApplication程序.
procedure DoneApplication;
begin
if Screen <> nil then
Screen.ActiveForm := nil;
Application.DestroyComponents; <-- this is destroying your main form
end;
Run Code Online (Sandbox Code Playgroud)
并DoneApplication在关机期间作为退出过程调用.退出proc是这样注册的TApplication.Run:
{$IFNDEF ANDROID}
AddExitProc(DoneApplication);
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
类构造函数从定义它们的单元的初始化部分调用.所以,TGlobalClass.Create从初始化调用uClassVar.类析构函数从同一单元的最终化部分调用.
系统关闭由System设备执行_Halt0.它在执行单元终结之前执行所有退出过程.因此,在调用类析构函数之前,您的表单将被销毁.
移动编译器
请注意,DoneApplicationAndroid上根本不会调用它.
{$IFNDEF ANDROID}
AddExitProc(DoneApplication);
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
这意味着主要表单的销毁是从单元终结中调用的.随着每个单元的最终确定,其执行的终结部分将导致任何全局变量离开范围.最终,没有更多对主表单的引用,因此它的析构函数被执行.
如上所述,类析构函数也从单元定型中调用.因为在Android上,你的类析构函数在主表单被销毁之前执行,所以很明显看到uClassVar在主表单的最终引用被释放之前已经完成.
现在,这是完全合理的,因为它uClassVar是初始化顺序中的最后一个单元,因此是最终化顺序中的第一个单元.如果您想确保uClassVar稍后完成,您需要安排它尽快初始化.例如,通过更改.dpr文件的uses子句,如下所示:
uses
uClassVar in 'uClassVar.pas',
System.StartUpCopy,
FMX.Forms,
ufmMain in 'ufmMain.pas' {fmMain};
Run Code Online (Sandbox Code Playgroud)
现在uClassVar是第一个初始化的单位,因此最后一个单位已经完成.
| 归档时间: |
|
| 查看次数: |
525 次 |
| 最近记录: |