[Qt-jambi-interest] Tracking down a problem in native-code
Tom Schindl
listom at bestsolution.at
Mon Nov 10 10:50:30 CET 2008
Hi Gunnar,
Gunnar Sletta schrieb:
> Tom Schindl wrote:
>> Hi,
>>
>> Well I now found how I can make my example not crash when I modify my
>> remove-method from:
>>
>>> public void remove(ModelElement element) {
>>> System.err.println("Removing: " + element);
>>> QListWidgetItem item = findItem(element);
>>> if( item != null ) {
>>> ((QListWidgetItemImpl)item).data = null;
>>> listWidget.removeItemWidget(item);
>>> }
>>> }
>
> removeItemWidget, removes a widget set on the item, not the item itself.
> To remove an item from a list you need to use takeItem(). In this
> scenario you haven't actually changed the listwidgets itemset at all.
Ok.
>
>> to
>>
>>> public void remove(ModelElement element) {
>>> System.err.println("Removing: " + element);
>>> QListWidgetItem item = findItem(element);
>>> if( item != null ) {
>>> ((QListWidgetItemImpl)item).data = null;
>>> item.dispose();
>>> }
>>> }
>>
>> everything works. Looks like a the garbage collection is to working
>> appropriately. Is 2nd snippet correct, Gunnar?
>
> When you explicitly call dispose() you will call the destructor of the
> item, which in turn will remove the item from the list. The code is
> certainly one correct way of doing it. The item will be deleted on the
> gui thread.
That's what I assumed.
>
>> If yes this pops up a
>> question should I not rely on Java-GC and dispose QObject's myself all
>> the time to ensure a valid state?
>
> No, you shouldn't. dispose() is an explicit delete and doesn't take into
> account other potential pointers to the same data. For QObjects we have
> a good chance of catching these things because QObjects have a deletion
> notification on the C++ side, but for non-QObjects, like
> QListWidgetItem, there could be scenarious where catching this is out of
> our control.
Ok. So I'm better of using takeItem. I guess the same is true for:
- QTableWidget:
Where I currently use #removeRow but should have used
#takeItem
- QTreeWidget:
Where I currently use #removeItemWidget() and
QTreeWidgetItem#removeChild but should have used #takeTopLevelItem
and QTreeWidgetItem#takeItem
When I currently completely refresh the List/Table/Tree structure I do a:
- QTreeWidget#clear()
- QTableWidget#clearContents()
- QListWidget#clear()
Is this correct or do I run in the same problems with my remove code?
>
>> I see this from the point of a library developer - What would you
>> suggest - should i dispose things explicitly when I don't need them any
>> more? What's better from a performance point of view, I guess dispose,
>> right because then the native resource is released immediately.
>
> For images I always dispose immediately, because they are expensive. For
> everything else, I normally rely on GC, because other objects are
> usually small enough to not make a "big" difference...
Ok. Thanks.
>
> ---
>
> But... Going back to the actual problem, the native crash... The problem
> is caused by the fact that we, when we mapped the API for QListWidget,
> did the same assumption you did, namely that removeItemWidget() removed
> the item. Under this assumption we de-reffed the instance, allowing
> garbage collection for the item even though it was still referenced by
> the QListWidget. GC would kick in and delete the item and if the GUI
> thread accessed the item at this time, this would have caused the crash.
Maybe the JavaDoc should clarify this whole situation.
>
> If you either use takeItem() or explicit dispose() this will not happen.
>
> Thank you a lot for finding this!
>
Thanks for your detailed explaination a have a final question to all
those Structured-Controls (List, Table, Tree).
Tom
More information about the Qt-jambi-interest
mailing list