一般来说,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