我在Android上使用QtQuick。
我正在尝试将带有数组属性的Javascript对象追加到ListModel
。
我使用LocalStorage
来存储此数据。
我从数据库中实现的对象具有此数组属性,当我尝试将该对象追加到ListModel
时,我得到了一个SEGFAULT。如果我没有在我的对象中包含数组,或者实际上如果数组为空,那么它将成功附加到ListModel
并且不会是SEGFAULT。
当我从数据库中实现对象时,我这样做:
var movie = {
id: row.id,
title: row.title,
genres: ['a', 'b', 'c']
}
我正在创建一个Javascript对象并从LocalStorage
结果集对象'行'中复制属性。出于这个问题,我只是硬编码数组,如上所示。当此对象附加到ListModel
它的SEGFAULT。
如果我完全删除了genres属性,或者甚至将它留在[]中,那么在附加时它不会是SEGFAULT:
var movie = {
id: row.id,
title: row.title,
genres: []
}
这是堆栈跟踪:
0 ListModel::set(int, QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b138
1 ListModel::append(QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b40a
2 ListModel::set(int, QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b26c
3 ListModel::append(QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b40a
4 QQmlListModel::append(QQmlV4Function*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542d21c
5 QQmlListModel::qt_metacall(QMetaObject::Call, int, void**) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x754347ea
6 QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Core.so 0x75054416
7 QV4::QObjectMethod::callInternal(QV4::CallData*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x753ac7c4
8 QV4::FunctionObject::call(QV4::CallData*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7537ed5e
9 QV4::__qmljs_call_property(QV4::ExecutionContext*, QV4::Referenced<QV4::String>, QV4::CallDataRef) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x75380962
10 ?? 0x7727c2e8
11 ?? 0x7727c2e8
使用完整的调试符号和单步执行构建Qt后,崩溃就在这里:
void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
{
ListElement *e = elements[elementIndex];
QV4::ExecutionEngine *v4 = object->engine(); <= SEGFAULT
当单步执行代码时,它似乎遇到了genres属性的Javascript数组值,ListModel
正在尝试创建子模型然后失败。这也是ListModel::set
函数中的这段代码的结果:
} else if (propertyValue->asArrayObject()) {
a = propertyValue;
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
int arrayLength = a->arrayLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
subModel->append(o, eng); <= This leads to the nested 'set' call above that crashes
}
那为什么会失败?
答案 0 :(得分:2)
此操作失败,因为不支持将非对象值(如文字字符串或整数)存储为数组中的属性值。
可以存储数组属性 ,但前提是数组中的每个项目都是对象,而不是基元或字符串文字。
这有效:
var movie = {
id: row.id,
title: row.title,
genres: [{name: 'a'}, {name: 'b'}, {name: 'c'}]
}