将带有 Javascript 数组的对象附加到 QML ListModel 会导致 SEGFAULT [英] Appending object with Javascript array to a QML ListModel causes SEGFAULT

查看:34
本文介绍了将带有 Javascript 数组的对象附加到 QML ListModel 会导致 SEGFAULT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Android 上使用 QtQuick.

I am using QtQuick on Android.

我正在尝试将具有数组属性的 Javascript 对象附加到 ListModel.

I am trying to append a Javascript object with an array property to a ListModel.

我使用 LocalStorage 来存储这些数据.

I use LocalStorage to store this data.

我从数据库中具体化的对象具有这个数组属性,当我尝试将该对象附加到 ListModel 时,我得到一个 SEGFAULT.如果我的对象中没有包含数组,或者实际上如果数组为空,那么它将成功附加到 ListModel 并且不会 SEGFAULT.

The object I materialise from the database has this array property, and when I try and append that object to the ListModel I get a SEGFAULT. If I do not include an array in my object, or in fact if the array is empty, then it will successfully append to the ListModel and will not SEGFAULT.

当我从数据库中具体化对象时,我这样做:

When I materialise the object from the database, I do this:

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

我正在创建一个 Javascript 对象并从 LocalStorage 结果集对象row"复制属性.为了解决这个问题,我只是对数组进行了硬编码,如上所示.当这个对象被附加到 ListModel 时,它就变成了 SEGFAULTs.

I'm creating a Javascript object and copying properties from the LocalStorage result-set object 'row'. For the sake of this issue, I just hard-code the array as you can see above. When this object is appended to the ListModel it SEGFAULTs.

如果我完全删除了流派属性,或者甚至像 [] 那样将其留空,它在附加时不会SEGFAULT:

If I remove the genres attribute completely, or even leave it empty as in [], it will not SEGFAULT when appended:

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 后,崩溃在这里:

After building Qt with full debug symbols and single-stepping, the crash is here:

void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
{
    ListElement *e = elements[elementIndex];

    QV4::ExecutionEngine *v4 = object->engine(); <= SEGFAULT

当单步执行代码时,它似乎遇到了流派属性的 Javascript 数组值,ListModel 试图创建一个子模型,然后它失败了.这也是在 ListModel::set 函数中作为这段代码的结果调用的:

When stepping through the code it seems when it encounters the Javascript array value for the genres property, the ListModel is attempting to create a sub-model and then it fails. This is called as a result of this piece of code also in the ListModel::set function:

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

那为什么会失败?

推荐答案

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

This fails because it is not supported to store non-object values such as literal strings or integers as property values in an array.

可以存储数组属性,但前提是数组中的每一项都是对象,而不是原始或字符串文字.

An array property can be stored, but only if each item in the array is an object, not a primitive or string literal.

这有效:

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

这篇关于将带有 Javascript 数组的对象附加到 QML ListModel 会导致 SEGFAULT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆