2014-04-10 28 views
3

我在Android上使用QtQuick。將JavaScript數組追加到QML ListModel導致SEGFAULT

我想追加一個數組屬性的Javascript對象到ListModel

我用LocalStorage來存儲這些數據。

從數據庫中實現的對象具有此數組屬性,當我嘗試將該對象追加到ListModel時,我得到一個SEGFAULT。如果我在對象中不包含數組,或者實際上如果數組爲空,則它將成功附加到ListModel,並且不會SEGFAULT。

當我兌現從數據庫中的對象,我這樣做:

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

我創建一個Javascript對象和複製從LocalStorage結果集對象「行」的性質。爲了這個問題,我只是硬編碼數組,如上所見。當這個對象被追加到ListModel它SEGFAULTs。

如果我刪除類型屬性完全,甚至讓它空在[],也不會追加當段錯誤:

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 

當steppin g通過代碼,當它遇到流派屬性的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

可以爲您提供可能崩潰的堆棧跟蹤?如果以調試模式啓動應用程序,則應該能夠在Qt Creator中看到C++堆棧跟蹤。 – Xander

回答

2

這會失敗,因爲不支持將非對象值(如文字字符串或整數)存儲爲數組中的屬性值。

陣列屬性可以被存儲,但只有當陣列中的每個項是對象,不是原始或字符串文字。

這工作:

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