diff options
author | Yulong Bai <yulong.bai@qt.io> | 2019-06-19 15:05:28 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@qt.io> | 2019-06-26 12:37:29 +0000 |
commit | b8a85408d943bffba403d783b9082bd279460bed (patch) | |
tree | 943887cbe495b8182930ac24325ce043f47b5374 /src/quick/items/qquickitemview.cpp | |
parent | 5eceb1801ec881947f80f70f32ea46e00926194f (diff) |
QQuickItemView: fix crash while doing fast flicking in transitions
The cause was that fast flicking kicked items in and out of viewport,
while in transition, they would abruptly having tracking data structure
, i.e. releasePendingTransition of QQuickItemViewPrivate, got iterator
invalidated. This also helps to resolve QTBUG-44308.
Fixes: QTBUG-76433
Fixes: QTBUG-44308
Change-Id: If14533d3f6b1acd7b6ca0c5c723347c0cb3f54dc
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src/quick/items/qquickitemview.cpp')
-rw-r--r-- | src/quick/items/qquickitemview.cpp | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 2e1962bc7b..eead84d51e 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1874,15 +1874,21 @@ void QQuickItemViewPrivate::layout() prepareVisibleItemTransitions(); - for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin(); - it != releasePendingTransition.end(); ) { - FxViewItem *item = *it; - if (prepareNonVisibleItemTransition(item, viewBounds)) { - ++it; - } else { - releaseItem(item); + for (auto it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) { + auto old_count = releasePendingTransition.count(); + auto success = prepareNonVisibleItemTransition(*it, viewBounds); + // prepareNonVisibleItemTransition() may invalidate iterators while in fast flicking + // invisible animating items are kicked in or out the viewPort + // use old_count to test if the abrupt erasure occurs + if (old_count > releasePendingTransition.count()) { + continue; + } + if (!success) { + releaseItem(*it); it = releasePendingTransition.erase(it); + continue; } + ++it; } for (int i=0; i<visibleItems.count(); i++) |