英才 發表於 2020-4-27 02:10:00

Delphi中initialization和finalization

<p>注:本文主要是讨论delphi程序启动时和退出时的执行顺序,期间有些知识来源于Delphi帮助,有些来自《Delphi7程序设计教程》(这本书只告诉我有initialization 和 finalization 这两个关键字,但是没讲明白)(唉,现在的书只讨论框框架架,不讨论细节,写出来的东西让你看能看懂,别人一问或者自己一想,就是什么都不懂!讲的不细致呀!唉,自己琢磨吧!!)。代码用两排‘*’标明。</p>
<p><br>好了,进入正题,首先说明initialization 和 finalization 在代码单元中的位置:<br>************************************************************<br>unit Unit1;</p>
<p>interface</p>
<p>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs;</p>
<p>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp;&nbsp;&nbsp; Button1: TButton;<br>&nbsp;&nbsp;&nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp;&nbsp;&nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; private<br>&nbsp;&nbsp;&nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; { Public declarations }<br>&nbsp; end;</p>
<p>var<br>&nbsp; Form1: TForm1;</p>
<p>implementation</p>
<p>uses Unit2;</p>
<p>{$R *.dfm}</p>
<p>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; ShowMessage('1 FormCreate');<br>end;</p>
<p>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; ShowMessage('1 Destroy');<br>end;</p>
<p>initialization<br>&nbsp; ShowMessage('1 ini');{单元初始化代码}<br>finalization<br>&nbsp; ShowMessage('1 final');{单元退出时的代码}</p>
<p>end.<br>************************************************************<br>initialization&nbsp;—— 在单元中放在文件结尾前,包含用来初始化单元的代码,它在主程序运行前运行并且只运行一次。<br>finalization&nbsp;—— 在单元中放在 initialization 和 end. 之间,包含了单元退出时的代码。在程序退出时运行并且只运行一次。<br>OnClose&nbsp;—— 在点击关闭按钮或执行该事件时调用。<br>OnCreate&nbsp;—— 在窗体创建时调用。(我的感觉:该事件是在窗体创建之后,即执行构造函数后才执行的)<br>OnDestroy&nbsp;—— 在窗体销毁时调用,一般用来销毁程序员自己定义(自己定义、创建,而不是直接从控件板拖拉过来的控件)的对象、变量、指针等等。(与析构函数的关系我还没弄清)</p>
<p>下面是执行顺序(如果程序中没有 initialization、 OnCreate、 OnClose、 OnDestroy、 finalization 中的任何一项,则相应跳过即可):<br>程序启动 --&gt; 执行 initialization 处的代码 --&gt; 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --&gt; 执行 OnCreate 事件 --&gt; 程序运行 --&gt; 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --&gt; 执行 OnClose 事件 --&gt; 执行 OnDestroy 事件 --&gt; 执行 finalization 处的代码</p>
<p>以上是对于单个窗体而言,下面是对于多个窗体:<br>新建一工程,创建3个Form,分别是form1、form2、form3,默认情况下form1为主窗体。<br>&lt;1 begin&gt;<br>程序启动 --&gt; 执行 initialization 处的代码(先 form1 然后 form2 最后 form3 ) --&gt; 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --&gt; 执行 OnCreate 事件(先 form1 然后 form2 最后 form3 ) --&gt; 程序运行 --&gt; 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --&gt; 执行主窗体的 OnClose 事件 --&gt; 执行 OnDestroy 事件(先 form3 然后 form2 最后 form1 ,注意哟,顺序倒过来了。) --&gt; 执行 finalization 处的代码(先 form3 然后 form2 最后 form1 ,注意哟,顺序倒过来了。)<br>&lt;1 end&gt;<br>为什么 OnDestroy 和 OnCreate 的顺序相反?为什么&nbsp; finalization和 initialization 的顺序相反?大家好好想想吧!</p>
<p><br>另外:如果我在form1中uses 一下Unit2(form2的代码单元)执行顺序如下:<br>&lt;2 begin&gt;<br>程序启动 --&gt; 执行 initialization 处的代码(先 form2 然后 form1 最后 form3 ) --&gt; 执行窗体的构造函数并创建相应窗体和单元中的对象(如拖拉的控件对象,全局变量等) --&gt; 执行 OnCreate 事件(先 form1 然后 form2 最后 form3 ) --&gt; 程序运行 --&gt; 关闭主窗体(此处指调用主窗体的Close或点击主窗体的关闭按钮) --&gt; 执行主窗体的 OnClose 事件 --&gt; 执行 OnDestroy 事件(先 form3 然后 form1 最后 form2 ,注意注意,不一样了。) --&gt; 执行 finalization 处的代码(先 form3 然后 form1 最后 form2 ,注意注意,不一样了。)<br>&lt;2 end&gt;</p>
<p><br>多个窗体(单元)一些细节性的东西:<br>1)initialization<br>initialization 的执行顺序取决于哪个窗体先被调用,对于&lt;1&gt;,由于3个窗体之间没有 uses 和被 uses 的关系,所以按照工程单元uses 中的顺序执行(在工程单元中,如下):<br>************************************************************<br>program Project1;</p>
<p>uses<br>&nbsp; Forms,<br>&nbsp; Unit1 in 'Unit1.pas' {Form1},<br>&nbsp; Unit2 in 'Unit2.pas' {Form2},<br>&nbsp; Unit3 in 'Unit3.pas' {Form3};</p>
<p>{$R *.res}</p>
<p>begin<br>&nbsp; Application.Initialize;<br>&nbsp; Application.CreateForm(TForm1, Form1);<br>&nbsp; Application.CreateForm(TForm2, Form2);<br>&nbsp; Application.CreateForm(TForm3, Form3);<br>&nbsp; Application.Run;<br>end.<br>************************************************************<br>如果改变<br>uses<br>&nbsp; Forms,<br>&nbsp; Unit1 in 'Unit1.pas' {Form1},<br>&nbsp; Unit2 in 'Unit2.pas' {Form2},<br>&nbsp; Unit3 in 'Unit3.pas' {Form3};</p>
<p>成为<br>uses<br>&nbsp; Forms,<br>&nbsp; Unit2 in 'Unit2.pas' {Form2},<br>&nbsp; Unit3 in 'Unit3.pas' {Form3},<br>&nbsp; Unit1 in 'Unit1.pas' {Form1};<br>那么就是(先form2后form3最后form1)<br>对于&lt;2&gt;,由于form1中uses了Unit2,那么在编译Unit1之前必须先编译Unit2。顺序自然是(先 form2 然后 form1 最后 form3)<br>所以&nbsp;initialization 的执行顺序首先看彼此单元之间是否有uses和被uses关系(简单的说就是:调用关系), 然后再看工程文件的uses的顺序。(呵呵,不要被uses弄混了!)</p>
<p>2)OnCreate<br>OnCreate 的执行顺序由工程单元中的如下类似代码决定<br>************************************************************<br>&nbsp; Application.CreateForm(TForm1, Form1);<br>&nbsp; Application.CreateForm(TForm2, Form2);<br>&nbsp; Application.CreateForm(TForm3, Form3);<br>************************************************************<br>改变之后则相应发生改变。</p>
<p>3)OnDestroy<br>与OnCreate的顺序相反。(相反时一种对应,创建的顺序与销毁的顺序是相反的,这样是为了避免发生错误,这样也体现了编程要求思维严谨。)</p>
<p>4)finalization<br>与 initialization 的顺序相反。</p>
<p>再说说OnClose,<br>当调用窗体的Close或点击关闭按钮时调用该事件。<br>主窗体Close后,程序就退出。<br>非主窗体Close,仅仅是Close本窗体。(别说你在OnClose中调用其他窗体的关闭,那些不再讨论范围)</p>
<p>直接用Application.Terminate强制退出程序时,不调用OnClose事件。但 OnDestroy 和 finalization&nbsp; 要执行。</p>
<p>说了这么多,不知道有没有说明白问题。希望大家能领悟(俺表达能力比较差,呵呵~~~)。</p>

</div>
<div id="MySignature" role="contentinfo">
    好的代码像粥一样,都是用时间熬出来的<br><br>
来源:https://www.cnblogs.com/jijm123/p/12783919.html
頁: [1]
查看完整版本: Delphi中initialization和finalization