2017-06-13 81 views
2

我已經註冊爲成分的TFrame的子類,我已經注意到,Loaded程序執行兩次:加載程序

運行:

TMyFrame = class(TFrame) 
    private 
    protected 
    procedure Loaded(); override; 
    public 
    constructor Create(AOwner : TComponent); override; 
    end; 

constructor TMyFrame.Create(AOwner : TComponent); 
begin 
    ShowMessage('Before TMyFrame.Create'); 
    inherited Create(AOwner); 
    ShowMessage('After TMyFrame.Create'); 
end; 

procedure TMyFrame.Loaded(); 
begin 
    ShowMessage('Before TMyFrame.Loaded'); 
    inherited; 
    ShowMessage('After TMyFrame.Loaded'); 
end; 

設計時:

procedure Register; 
begin 
    RegisterComponents('Test', [TMyFrame]); 
end; 

輸出:

在運行時,創建一個表單,其中有一個TMyFrame組件。

TMyFrame.Create

之前

之前TMyF​​rame.Loaded

後TMyFrame.Loaded

TMyFrame.Create

之前TMyF​​rame.Loaded

TMyFrame.Loaded後後

在設計時,就加入了TMyFrame到窗體:

TMyFrame.Create

之前

之前TMyF​​rame.Loaded

後TMyFrame.Loaded

TMyFrame.Create

在設計時,op付民的形式,其中有一個TMyFrame成分:

之前TMyF​​rame.Create

TMyFrame.Loaded

之前

後TMyFrame.Loaded

後TMyFrame.Create

之前TMyFrame.Loaded

TMyFrame.Loaded

爲什麼Loaded過程被執行兩次?如何避免這種情況?

+0

如果使用調試DCU進行編譯,您可以設置斷點並查看調用堆棧。 –

+0

*當*看到這些信息時?在IDE中?或在運行時?如果在IDE中您並不在意,那麼可以使用針對componentstate = csDesigning的測試來包圍消息。 – Dsm

+0

@Dsm:「在運行時向表單添加TMyFrame後」。 –

回答

7

此行爲是按設計的。

Loaded

加載可以在遺傳形式的多次調用。在每次繼續傳輸繼承級別時,它都被稱爲 。不要在重寫的Loaded方法中分配 內存,而不必先檢查是否在先前的調用中分配了內存 。

+0

你知道一種區分上次執行的方法嗎? (在本質上,我想使用一些在構造函數中初始化的變量) – ExDev

+0

不可能。最可能最安全的事情是將代碼從'Loaded'移動到'AfterConstruction'。 –