Delphi 释放包含TJvAppDBStorage的数据模块会在TComponent.RemoveNotification()中引发访问冲突

Delphi 释放包含TJvAppDBStorage的数据模块会在TComponent.RemoveNotification()中引发访问冲突,delphi,delphi-xe2,jvcl,Delphi,Delphi Xe2,Jvcl,我有一个无法释放的数据模块(听起来很有趣)。无论我试图手动销毁它,还是让另一个组件(甚至是应用程序)为我销毁它,我都会得到一个具有以下堆栈跟踪的AV: exception class : EAccessViolation exception message : Access violation at address 0048FC2B in module 'Instruments.exe'. Read of address 80808088. main thread ($1e28): 004

我有一个无法释放的数据模块(听起来很有趣)。无论我试图手动销毁它,还是让另一个组件(甚至是
应用程序
)为我销毁它,我都会得到一个具有以下堆栈跟踪的AV:

exception class   : EAccessViolation
exception message : Access violation at address 0048FC2B in module 'Instruments.exe'. Read of address 80808088.

main thread ($1e28):
0048fc2b Instruments.exe System.Classes    TComponent.RemoveNotification
00408a01 Instruments.exe System         57 @Halt0
00ac86f0 Instruments.exe Instruments    82 initialization
此数据模块包含一组
TADOxxx
组件,外加两个
TJvDataSource
、一个
TApplicationEvents
、一个
TClientDataSet
、一个
TJvAppDBStorage
。它的代码只包含打开ADO连接、向表中写入一些记录、运行一些查询等内容(没有什么异常)。除了我上面提到的,它没有任何其他组件。我不知道这个对
RemoveNotificaion()
的伪调用是从哪里来的。有什么想法吗

更新

删除
TJvAppDBStorage
后,我可以销毁数据模块。以下是组件的属性:

object AppStorage: TJvAppDBStorage
  StorageOptions.BooleanStringTrueValues = 'TRUE, YES, Y'
  StorageOptions.BooleanStringFalseValues = 'FALSE, NO, N'
  DataSource = dsConfiguration
  KeyField = 'Key'
  SectionField = 'Section'
  SubStorages = <>
  ValueField = 'Value'
  Left = 272
  Top = 304
end
对象应用存储:TJvAppDBStorage
StorageOptions.BooleanStringTrueValues='TRUE,YES,Y'
StorageOptions.BooleanStringFalseValues='FALSE,NO,N'
数据源=dsConfiguration
KeyField='Key'
SectionField='Section'
子存储=
ValueField='Value'
左=272
顶部=304
结束

是否有人使用过
JvAppDBStorage
?这是正常的和预期的行为吗?

我没有使用
JvAppDBStorage
的经验,但我可以猜测到底发生了什么

此组件将设置存储到数据库,如
JvAppDBStorage
实例的
DataSource
属性所指定。在您的情况下,这是
dsConfiguration
。因此,要使这一切正常工作,您需要
dsConfiguration
AppStorage
读取和写入设置时可用。我敢打赌
dsConfiguration
AppStorage
尝试存储到它时已经被销毁。我希望当
AppStorage
被释放时会发生这种情况。因此,问题的解释是,
dsConfiguration
AppStorage
之前被释放


解决方案是确保
dsConfiguration
AppStorage
被释放时仍处于活动状态。

我认为
应用程序
应该是更好的所有者。也就是说,为什么不继续传递
nil
,而是自己在数据模块上调用
Free
。如果您需要调试AV的帮助,请提供更多信息。提供准确的错误消息、引发错误的代码和调用堆栈。@DavidHeffernan更新了问题。。。正如堆栈跟踪所示,我的代码中没有引发异常。是的,这是意料之中的。您在哪里创建数据模块?在你的.dpr文件中?如果是这样,我建议您在
应用程序之后调用
Free
。Run
返回。不要让它归主窗体所有。因此,作为所有者继续传递
nil
。如果失败了,那么我们至少可以更好地控制何时调用析构函数。而且调试会更容易。@DavidHeffernan我正在主窗体的
OnCreate()
中创建数据模块。当我将
nil
作为
Owner
传递时,我会在主窗体的
OnDestroy()
中释放它。如果在
OnDestroy
中释放它,则应该没有泄漏。更改
所有者
对您没有帮助。再次感谢您的回答。我刚刚剪切并粘贴了
JvAppDBStorage
组件,问题就解决了:-)