我試圖測試QML以瞭解它如何與C++一起工作。我有ClassA
和ClassB
- 2個類似的C++類。這是一個ClassA
。所有的方法都是用自己的名字來解釋,所以我不會在這裏放置實現。QML內存管理
class ClassB;
class ClassA : public QObject
{
Q_OBJECT
public:
explicit ClassA(QObject *parent = 0);
~ClassA();
Q_PROPERTY(ClassB* classB READ getClassB WRITE setClassB NOTIFY classBChanged)
ClassB* getClassB() const;
void setClassB(ClassB *classB);
signals:
void classBChanged();
private:
ClassB *m_classB;
};
ClassB
是一樣的,只是改變所有*lassA*
到*lassB*
和所有*lassB*
至*lassA*
。
然後我註冊在QML都歸類與
qmlRegisterType<ClassA>("testmodule.test",1,0,"ClassA");
qmlRegisterType<ClassB>("testmodule.test",1,0,"ClassB");
並在鼠標QML
代碼單擊創建兩個對象是這樣的:
onClicked: {
var comp = Qt.createComponent("TClassA.qml"); //TClassA.qml is
//a component of type
//ClassA
var ca = comp.createObject();
comp = Qt.createComponent("TClassB.qml");
var cb = comp.createObject();
ca.classB = cb;
cb.classA = ca;
parent.blockFromGC = ca;
}
此後,我稱之爲垃圾收集與gc()
。我預計ca
被阻止從parent.blockFromGC
刪除和cb
被阻止從ca
刪除參考。但垃圾收集器銷燬cb
,之後parent.blockFromGC.classB === null
。
所以我有第二MouseArea
與此代碼:
onClicked: {
console.log(mouse.button)
// if (mouse.button == Qt.RightButton) {
// console.log(parent.vasya.classB)
// }
gc();
console.log(parent.blockFromGC.classB) //I use cb here
}
所以,當我點擊MouseArea
我在控制檯中看到:
qml: 1 //Left button
qml: null //value of parent.blockFromGC.classB
classB destroyed: TQMLClassB(0x34960d0) //I have qDebug() in destructor
所以我的目標cb
被摧毀。
所以我有這樣的問題:
1)是否有一種方法,我怎麼能註冊一個C++
型爲基本型,這樣我就可以 寫var ca = new ClassA()
而不是創建一個*.qml
文件,創建一個組件,並最終創造一個東西?
2)爲什麼垃圾收集器破壞了我的cb
對象,我應該怎麼做 以防止刪除此對象?
此外!如果我取消註釋那些註釋行
// if (mouse.button == Qt.RightButton) {
// console.log(parent.vasya.classB)
// }
無論按下哪個按鈕,對象都不會被銷燬。
qml: 1 //left button
qml: TQMLClassB(0x3df8e90) //object is alive
.....
qml: 2 //right button
qml: TQMLClassB(0x3df8e90) //before gc() - alive
qml: TQMLClassB(0x3df8e90) //after gc() - alive
3)在哪裏可以閱讀關於QML
內存管理的詳細資料?我覺得這種行爲真的很奇怪..
加法1:我玩這種情況多一點,結果是不可預知的。我從5.3更新到Qt 5.4,這種刪除對象的行爲已經消失。問題在於行爲如此不可預測,以至於我無法在Qt 5.4中重現這種行爲,並不意味着問題得到解決。我會嘗試查看錯誤報告和錯誤修復。如果我找到了什麼,我會在這裏發佈。如果沒有,我會嘗試在Qt 5.4中重現這種情況併發布報告。
你可以把'ClassA'放入一個'Component'中,然後通過'var ca = thisComponent.createObject(parent)'創建它。至於對象破壞 - 你能確定在哪個步驟調用了desctructor?正如我所知道的,如果沒有引用它,那麼你就不得不以這種方式尋找對象。 – folibis
@folibis在調試模式下,這個問題成爲一個概率問題。有時它發生了,有時並沒有發生。跟蹤沒有給我太多的信息。如預期的那樣,所有函數調用都在共享庫中完成,其中一些已隱藏。而且它們都具有通常的名稱,用於試圖刪除和反對的功能。無論如何,讀一個補充發布,並感謝您的建議如何不需要創建* .qml文件。 – JustAnotherCurious