March 27, 2012

void7910 void7910
Lab Rat
2 posts

Memory management of objects handed back to QML

 

I have a helper class that maintains a little context that I’d like to pass back to qml through an invokable as a pointer. What’s the easiest way to cleanup the object when the javascript funcTion is done with it? I’m hoping there’s a Qt’ism for this as I’d rather not have to implemet a clean up function to delete it from qml.

Thanks

3 replies

March 27, 2012

chriadam chriadam
Ant Farmer
181 posts

QML already does this. A QObject which is returned to QML from an invokable function as a return value has its ownership semantics set to JavaScriptOwnership if it has not previously been explicitly set to CppOwnership. Thus, when you’ve finished using it, the garbage collector should be able to collect it (assuming no other JS references to it exist).

Calling gc() occasionally during debugging/development and using qDebug() statements in your dtors (or console.log()s in Component.onDestruction handlers) is a good way to trace deletions, however be aware that QObject deletions triggered by the garbage collector are deleteLater()s, so you’ll need to process deferred deletion events before you’ll see those dtors show up.

March 27, 2012

void7910 void7910
Lab Rat
2 posts

Thanks. Interesting I didn’t know this. Is it documented somewhere? My only concern is that someone could call the method directly in c++ where there would be no GC. Would returning a QSharedPointer solve both cases? I’ve been trying this method, but I keep getting a seg fault deep down in Qt during atomic deref in ASM.

March 28, 2012

chriadam chriadam
Ant Farmer
181 posts

It is documented, although perhaps not conspicuously enough. See the ObjectOwnership enum docs at http://doc.qt.nokia.com/4.7-snapshot/qdeclarativeengine.html for the description of the semantics.

If they call the method directly in C++ you’re right – you’d have to manually manage the lifetime of the object returned. Furthermore, even in JS you have no guarantee that the garbage collector will ever run (eg, if the system doesn’t get low on memory, a garbage collect won’t be triggered) and thus you’d either have to manually call gc() or risk having the dtor of the object not called until the application exits (the gc() is always run just prior to application exit, at least in QtQuick2).

A QSharedPointer probably wouldn’t work, as far as I know. I don’t actually know how QML would handle that case (it may actually use the automatic conversion to QObject* and manage the lifetime without the locking/etc provided by the shared pointer, which could cause the segfault you’re seeing – although that’s all surmise and could very well be wrong).

 
  ‹‹ QML ListView individual item spacing      [Solved] How to change the default font of QML? ››

You must log in to post a reply. Not a member yet? Register here!