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
组件,问题就解决了:-)