我正在使用UI。 UI组件的基类是UILayout
,整个UI是UILayout对象的树,根是代表整个屏幕的UILayout。为了包含此层次结构,任何给定的UILayout都有一个boost::shared_ptr<UILayout>
的 vector mChildren 。
UIManager对象负责更新UILayouts的整个层次结构。每次对Update的调用都会在 vector mChildren上进行迭代,并递归地对每个 child 调用Update。
因为更改 vector 的形状会使这些迭代器无效,所以将mChildren中的条目添加和删除仅限于ResizeChildren方法。当需要添加或删除组件时,会将它们添加到两个 vector mChildrenPendingAddition和mChildrenPendingRemoval之一。在Update循环之前,立即调用ResizeChildren,并相应地更新mChildren。 (如果这是处理此特定问题的一种明智方法,请阻止我。)
当我尝试从mChildren中删除所有也包含在mChildrenPendingRemoval中的条目时,出现异常。从UILayout::ResizeChildren():
mChildren.erase(remove_if(mChildren.begin(), mChildren.end(),
IntersectsWithChildrenPendingRemoval(this)), mChildren.end());
IntersectsWithChildrenPendingRemoval的比较函数调用this-> ChildrenPendingRemovalContains(HUILayout ly),该函数执行以下操作:
return (find(mChildrenPendingRemoval.begin(), mChildrenPendingRemoval.end(),
ly) != mChildrenPendingRemoval.end());
该行有时会使调试断言 vector 迭代器不兼容失败。关于此错误有很多现有的问题,但似乎通常表明正在比较来自不同容器的两个迭代器。但是在这里,事实显然并非如此,对吧?还有什么可能导致此问题?
相关源代码:
这是我正在为多线程应用程序开发的插件。问题以非常罕见且随机的间隔出现的事实使我相信,这与插件在单独的线程中运行有关,但是所有这些方法都是从单个函数(直接在单个函数中)调用的线程,并且在任何其他线程中都不能访问或修改mChildren。
最佳答案
您为什么不处理集合的拷贝,然后一次交换它:
std::list<X> copy(mChildren);
copy.insert(...);
copy.remove(...);
copy.insert(...);
// at once:
std::swap(copy, mChildren);
进一步的想法: