将带有Javascript数组的对象附加到QML ListModel会导致SEGFAULT

时间:2014-04-10 09:43:02

标签: android qt qml qt5 qtquick2

我在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
        }

那为什么会失败?

1 个答案:

答案 0 :(得分:2)

此操作失败,因为不支持将非对象值(如文字字符串或整数)存储为数组中的属性值。

可以存储数组属性 ,但前提是数组中的每个项目都是对象,而不是基元或字符串文字。

这有效:

var movie = {
    id: row.id,
    title: row.title,
    genres: [{name: 'a'}, {name: 'b'}, {name: 'c'}]
}