12-03-2012 07:37 AM
12-03-2012 08:19 AM
12-03-2012 09:16 AM
Are you still passing the object in using a signal as well?
Don't want to tell you stuff you already know but a seg fault is a memory access violation - the most common cause for that in application code by a mile is trying to access a pointer to an object that has already been deleted.
What owns the object you're trying to access and what is its lifetime? If you're managing that youself then you might have a bug there. If you're not sure (e.g. didn't set a parent) then it's possible you've passed ownership to the declarative engine and it has deleted it upon exiting the signal handler.
The link I posted earlier has all the nasty details on sharing access to objects with QML.
One other alternative to passing an object in a signal at all is to simply add the object to the root context and send a signal to say it's there. You can then copy the bits you want from the root context to the relevant QML properties to keep everything looking nicely structured (accessing things from the root context looks a bit much like global variables - even if just about everything in QML/JS is global anyway).
Hope that helps,
Mark
12-03-2012 09:35 AM
My plan is to have all QObjects linked in a tree, to clean up the memory, but at the moment i am just creating them without any deletion.
So (at least i think) the lifetime should be unlimited. Here is the part where i create it (it gets some more details etc, but that would be the basics):
QString errorMessage = soapStruct["Error"].toString();
DataServiceError* dsError;
if (!errorMessage.isEmpty()){
dsError = new DataServiceError();
dsError->setErrorMessage(errorMessage);
Could it be an issue that i currently don't set the parent for a new QObject? I want to utilize that when i add the clean-up code, but it is not there yet.
My latest approach was to send a signal "dataStored" and let the qml retrieve it itself, but this does not work either.
12-03-2012 09:57 AM - edited 12-03-2012 09:59 AM
I'm not entirely clear on exactly what you're doing to share the data with QML now. For example, calling methods on an object that's been deleted is just as bad as trying to read data in an object that's been deleted. ![]()
If you just create the object with new, don't set a parent in the constructor and let the pointer go out of scope then it will not be deleted unless you pass ownership somewhere - actually this is a classic source of memory leaks. However, depending on how you pass the object into QML, the declarative engine may take ownership if it doesn't have a parent set. Then the declarative engine decides (possibly incorrectly) when it is out of scope and should be deleted.
If you can post some more code, or a small example that reproduces the problem then I'd be happy to take a look. Otherwise I'd suggest either creating the object from QML and managing the whole process via signals/Q_INVOKABLE functions so that the object lifetime is entirely managed by the declarative engine, or adding the object to the root context and signalling that it's available.
12-03-2012 10:03 AM
12-03-2012 10:12 AM - edited 12-03-2012 10:14 AM
>> I made some getters and declared them Q_INVOKABLE.
>> After receiving the result from my webservice i store it and send a signal to the QML, which uses the invokable methods to access the objects.
This is the critical bit... what class has the Q_INVOKABLE getters and how is the instance of it which stores the result from the webservice made visible to QML?
>> Without having a clue, it sounds reasonable that the engine assumes ownership, as i just create the object and throw it out there. The article you linked states that Q_INVOKABLE does not change the ownership though.
Calling a Q_INVOKABLE method will not cause owership to change but before you can do that, you must somehow pass the object to the declarative engine. If you just called the getter on an instance of the type registered, QML would create a new object. This is the bit I'm not entirely understanding at the moment.
>> I don't think i can create a sample that reproduces the issue, the application is a port of existing apps on BB OS, Android and iOS and not very small...
Yes, actually I'd happily try the whole project with details of relevant files/lines to look at but most people are not so happy sharing all of their code. ![]()
12-03-2012 10:41 AM
I have dubbed a class "DataService", it is created in the main class of the project and put into the qml using
qml->setContextProperty("dataService", dataService);
in qml i use it like this:
function requestData() {
//connect signals from dataservice
dataService.dataServiceResultStored.connect(onData ServiceResultStored)
activityIndicator.start();
dataService.loadDataServicesData(backendId, pageName, pageId);
}
dataservice then sends the signal dataServiceResultStored and the function onDataServiceResultStored is triggered.
there i am trying to access the get methods from dataservice, which are all declared Q_INVOKABLE.
12-03-2012 11:36 AM
Sounds like the object lifetime shouldn't be an issue - depends which overload of setContextProperty() is being used as to which environment owns the object I believe but it should be OK in any case - I assume you can still access other dataService methods?
Out of interest, why use separate getters here rather than simply setting properties of the dataService object?
12-03-2012 12:14 PM