如何清理或销毁 QJSEngine?
Posted
技术标签:
【中文标题】如何清理或销毁 QJSEngine?【英文标题】:How to clean up or destroy QJSEngine? 【发布时间】:2019-04-11 15:30:55 【问题描述】:我正在使用 Qt 5.12 构建一个应用程序,用户将在其中加载通过其 API 与应用程序交互的 JS 脚本。这些脚本被捆绑到“项目”中(即多个相互依赖的 JS 模块),并且在任何时候我都希望只将一个项目加载到 JS 引擎中,所以如果用户加载不同的项目,我想要前一个要清理的上下文。
根据文档,我假设如果我只是删除 QJSEngine 对象并创建一个新对象,这将允许我创建一个新的 JS 上下文。
QJSEngine* jsEngine = new QJSEngine();
// Load JS modules and run code...
jsEngine->collectGarbage();
delete jsEngine;
jsEngine = new QJSEngine();
// Load new JS modules...
当我尝试运行此代码时,我在delete jsEngine
处收到访问冲突异常。这真的很奇怪,因为文档本身就说明了
QJSEngine 销毁期间不会从持久 JS 堆中收集垃圾。如果您需要释放所有内存,请在销毁 QJSEngine 之前手动调用 collectGarbage。
这对我来说意味着我应该能够做到这一点。有人有想法么?提前致谢!
【问题讨论】:
我什至尝试使用deleteLater
,或者将主窗口设置为我创建的每个 QJSEngine 的父窗口(因此在关闭应用程序时清理它们),但问题仍然存在。出于某种原因,当我拥有多个实例时,或者如果我尝试在应用关闭时以外的任何其他时间删除一个实例,我就会遇到某种内存访问错误。
【参考方案1】:
好吧,原来我是个傻瓜,忘记包含一个重要细节:我的应用程序还使用QJSEngine::newQObject
向 JS 引擎公开了我的“javascript 接口”对象,所以我几乎只是重新创建 @987654321 @。
解决方案完全相同:使用QQmlEngine::setObjectOwnership
可以解决问题。
【讨论】:
【参考方案2】:确保周围没有任何剩余的 QJSValue。
或者,如果您只想清理状态。清除 QJSEngine::globalObject(),或者只是避免使用根 JS 状态,这样项目之间就不会泄漏。
【讨论】:
好的,我刚刚发现问题的根源是:我使用newQObject
将我的“接口”类暴露给 JS 全局对象(我让对象在调用时给自己一个指针函数),当我尝试删除 QJSEngine 时,这会导致崩溃。但是现在我要在删除之前“清理它”吗?我尝试在全局对象上使用“deleteProperty”,但没有奏效。
好问题。我会假设您需要以某种方式停止引用它,然后激活垃圾收集。请注意,桥接对象也有不同的所有权模型(如果我没记错的话,可以控制 C++ 或 JS)
见上面的答案。事实证明有一个直接的解决方案,但得到它是相当不直观的。不过,感谢您的 cmets,他们确实帮助我找到了正确的答案。以上是关于如何清理或销毁 QJSEngine?的主要内容,如果未能解决你的问题,请参考以下文章