一般來說,AV是某些代碼試圖調用一個不再存在的東西的例程的信號。
從這個角度看,一個AV爲這個特定的析構函數的結果可能表明兩種情況之一:
SurveyForm
不存在了,或者
- 代碼爲
SurveyForm.Click
結果預計將組件的存在,以是真的,但組件無論如何都會被銷燬。
名稱Click
暗示SurveyForm
是一個按鈕式控件。如果該控件不是你的組件的一部分,而是組件所在表單的一部分,那麼前者(情況1)當然可以是真的:表單的析構函數已經銷燬了SurveyForm
,現在即將銷燬你的組件。你可以通過使用BeforeDestruction
來防止這種情況,正如雷米已經提到的那樣。另外(但只是一般性的提示,而不是解決你的問題),你可以通過註冊該組件給你自己來通知它的銷燬,從而防止使用被銷燬的組件。與FreeNotification
結合覆蓋Notification
爲此在你無組件:
procedure TqqFormLogger.SetSurveyForm(Value: TForm);
begin
FSurveyForm := Value;
FSurveyForm.FreeNotification(Self);
end;
procedure TqqFormLogger.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = FSurveyForm) and (Operation = opRemove) then
FSurveyForm := nil;
end;
destructor TqqFormLogger.Destroy;
begin
if FSurveyForm <> nil then
...
如果控制確實是你的組件的一部分,那麼我懷疑背後Click
代碼允許組件的析構函數的過程使用無論如何(案2)。例如,在發佈消息(手動或由於VCL或Windows內部結果)時,將在消息驅動或處理之前調用inherited Destroy
。
簡而言之:現在的問題太籠統了,無法給出具體的答案。
做你正在做的事情沒有問題。不可能說爲什麼它不適合你。什麼是SurveyForm?任何更多代碼的機會,所以我們可以看到AV在哪裏。 – 2012-04-02 21:11:49
對不起,沒有那麼清楚。我所擁有的是一個名爲「FormLogger」的組件,它放置在我們項目的所有表單上。在項目運行時,該組件會創建一個TButton(稱爲SurveyButton),如果單擊它,將打開一個表單(SurveyForm)。到目前爲止,這部分工作正常。但是,我們希望每次關閉表單時都打開SurveyForm(即觸發SurveyButton.Click事件)。這似乎是SurveyButton時。點擊是在我的組件的析構函數中觸發的,承載組件的主窗體已經被銷燬。有解決方案嗎?謝謝 – user1202134 2012-04-05 14:42:31
表單自動調用設計時組件上的FreeNotification()(它依次調用窗體的FreeNotification()方法)。您的組件可以覆蓋它的'Notification()'方法來檢測表單何時被釋放。或者,如果您有任何在關閉時沒有立即釋放的表單,則您的組件的構造函數可以將事件處理程序分配給表單的「OnClose」事件。 – 2012-04-05 16:04:16