2012-08-04 41 views
7

我已經具有TComponent的可變的單元,創建關於該單元的初始化這個組件像以下:可否使用.Create(無)代替.Create(應用)

var 
    XComp: TComponent; 
. 
. 
. 
. 

initialization 
begin 
    XCom := TComponent.Create(Application); 
end; 

安裝後當我關閉德爾福它給了我一個訪問衝突錯誤消息(EAccessViolation)

但單位時,我改變了我的創造者是如下

initialization 
begin 
    XCom := TComponent.Create(nil); 
end; 

一切正常......我想知道區別?什麼更好?

注意:錯誤只出現在關閉delphi(意味着在設計時)。

謝謝。

+0

這裏是[後面的一個'](http://stackoverflow.com/q/5420260/960757)。 – TLama 2012-08-04 20:57:31

+6

您正在'initialization'部分創建'XCom'。你是否還有一個'finalization'部分以釋放它? – 2012-08-04 21:17:38

回答

2

基本上都被允許的,即使你有這樣的代碼應該不會導致AV:

MyComp := TMyComp.Create(Application); 
try 
    {...} 
finally 
    MyComp.Free; 
end; 

這是因爲當它是一個正確編碼的組件將自己從它的主人的組件列表中刪除銷燬。

我認爲這裏的問題可能是組件已經被應用程序對象釋放,後來一些代碼試圖訪問它。也許在你的代碼中有一個finalize部分,那是否?或者你可能有混合的對象和接口和引用計數得到你。

要調試您的問題,您可以通過將包的「主機應用程序」設置爲Delphi(C:\ Program Files \\ BDS \\ Bin \ bds.exe)來在調試器中運行IDE。 並在你的組件的析構函數中設置一個斷點。這樣你就會發現它被釋放的位置以及AV的出現位置。

13

當您使用

XCom := TComponent.Create(Application); 

你做應用XCOM的所有者。當應用程序終止時,它將負責銷燬XCom,因爲它是所有者。

當你

XCom := TComponent.Create(nil); 

沒有人XCOM的所有者,你必須在應用程序終止自己釋放它。

您可能得到了異常,因爲您手動釋放了XCom,然後Application也試圖釋放XCom。

+5

+1。作爲一般指南:當你自己釋放對象時使用'nil',如果你不需要''Application'並且你希望它爲你清理,或者如果有可能你不能釋放它你自己。 – 2012-08-04 17:27:38

+1

@birger:如果組件編碼正確,它將在被釋放時從自己的組件列表中刪除(在這種情況下:應用程序)。所以理論上AV不應該發生。我認爲這可能是相反的方式:組件已經被應用程序釋放,然後程序試圖訪問它。如果我正確地解釋了這個問題,這是一個designtime包中的一個組件,AV出現在Delphi IDE中,所以這有點複雜。 – dummzeuch 2012-08-05 10:00:36

相關問題