aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-01-09 14:31:27 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-01-10 13:03:04 +0100
commit490f787a1ebe3cee8e9f7793bb6919295b2aea47 (patch)
tree34513eb6a3c15d1cf184745cd9c36b82fe1595ba
parent3c23f5371a19991771bd29c27d377c6672e46cd1 (diff)
QQuickItemView: Fix iteration/deletion logic
If a QVector has been modified from the outside, all its iterators are invalid. Therefore, we need to do index-based iteration here. Change-Id: I02b850daf6aadd8f8a81cc93b0d295e1170d7dd6 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/quick/items/qquickitemview.cpp28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 66be3c79f8..b5fb12fe89 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1908,21 +1908,25 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
- 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()) {
+ // We cannot use iterators here as erasing from a container invalidates them.
+ for (int i = 0, count = releasePendingTransition.count(); i < count;) {
+ auto success = prepareNonVisibleItemTransition(releasePendingTransition[i], viewBounds);
+ // prepareNonVisibleItemTransition() may remove items while in fast flicking.
+ // Invisible animating items are kicked in or out the viewPort.
+ // Recheck count to test if the item got removed. In that case the same index points
+ // to a different item now.
+ const int old_count = count;
+ count = releasePendingTransition.count();
+ if (old_count > count)
continue;
- }
+
if (!success) {
- releaseItem(*it);
- it = releasePendingTransition.erase(it);
- continue;
+ releaseItem(releasePendingTransition[i]);
+ releasePendingTransition.remove(i);
+ --count;
+ } else {
+ ++i;
}
- ++it;
}
for (int i=0; i<visibleItems.count(); i++)