From 490f787a1ebe3cee8e9f7793bb6919295b2aea47 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 9 Jan 2020 14:31:27 +0100 Subject: 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 --- src/quick/items/qquickitemview.cpp | 28 ++++++++++++++++------------ 1 file 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