我目前正在实现基于XML和Javascript的用户界面。我写了很多包装类,到目前为止一切正常。只有一件事让我烦恼。我无法从我的一个函数的参数创建持久对象。说我有以下功能:
void UIManager::registerJSObject(JSObjectPtr objPtr) {
使用我的包装器向Javascript注册JSObject(包装v8 :: Handle)指向本地函数参数,因此在函数被删除之后。现在很明显这不是我想要的。
我的第一种方法是将一个makePersistent方法添加到JSObject类中:
void JSObject::makePersistent() {
v8::Persistent<v8::Object> newObj = v8::Persistent<v8::Object>::New(mObject);
mObject = newObj;
}
可悲的是它没有用,对象仍然被垃圾收集。所以我想也许它太晚了,当我在那里做它并且由于某种原因它已经从回调的Arguments参数中取出时已经被转换,并且我将我的包装器改为此(仅用于测试):
template<uint32 size, typename T, typename... FullArgs, typename... Args>
Res expand(const v8::Arguments& args, Args... curArgs) {
return expand<size + 1, FullArgs...>(args, curArgs..., ObjectWrap::unwrap<T>(v8::Persistent<v8::Value>::New(args[size])));
}
可悲的是,那也不起作用。我无法获得javascript中分配的对象的持久句柄。我在谈论那段代码:
var frame = {
xmlTemplate: "testXml.xml",
onTemplateLoaded: function () {
this.frame1.button1.Caption = "Test";
},
buttonClicked: function(button) {
button.Caption = "Clicked";
}
};
UIMgr.loadUIElement(frame);
和id喜欢调用buttonClicked函数或者不仅在UI.load函数中设置一些字段,而且稍后也设置。
有人知道我是否遗漏了某些东西或者这是一个错误吗?
问候Muepe
答案 0 :(得分:0)
好的,我找到了解决方案。我已经在正确的轨道上,必须在原始对象上创建持久句柄,所以我使用第二个重载修改了我的扩展成员函数,特别是对于应该获得JSObject的参数。
与以前一样:
template<uint32 size, typename T, typename... FullArgs, typename... Args>
typename std::enable_if<std::is_same<T, JSObjectPtr>::value, Res>::type expand(const v8::Arguments& args, Args... curArgs) {
return expand<size + 1, FullArgs...>(args, curArgs..., ObjectWrap::unwrap<T>(v8::Persistent<v8::Value>::New(args[size])));
}
有趣的部分是在ObjectWrap :: unwrap for JSObjectPtr:
template<typename T>
static typename std::enable_if<std::is_same<T, JSObjectPtr>::value, JSObjectPtr>::type unwrap(v8::Persistent<v8::Value> val) {
v8::Persistent<v8::Object> objh = v8::Persistent<v8::Object>::Cast(val);
return std::make_shared<JSObject>(objh);
}
HAS 作为v8 :: Persistent传递给函数,否则它不会工作。
JSObject有一个持久句柄的构造函数,并将它转换为一个弱引用,当没有人再使用JSObject时会被调用(那就是当它实际上必须被收集时)。