我有一个Layer类,其中包含某些对象,如按钮,滑块等。我已经构建了Layer类,以便它能够自我刷新。基本上,它删除所有/大多数对象,然后重新创建它们。原因是我有各种功能,如更改字体大小或我的UI的主题,我希望立即显示更改。
实现此目标的唯一方法是简单地重建所有内容,因为主题和字体大小会影响所有内容的外观和布局。这一切都很有效,我对系统感到满意。
但是,当属于该层的对象启动刷新时,会出现问题(以及我所说的崩溃问题)。例如,我有一个字体大小滑块,它应该改变字体大小然后刷新图层。它具有对层的刷新功能的回调,由lambda捕获,并存储在成员std :: function对象中。执行该函数时会发生的情况是,在某个时刻,在调用函数完成之前,滑块当然会被破坏并随之破坏该函数。因此,当前运行的功能停止存在并且程序崩溃。
我的问题是,通过这种自相矛盾的情况,实现这种不会导致崩溃的行为会是一种优雅而优雅的方式吗?
编辑:代码
class MySlider : public MyNode
{
//... various other class members
std::function<void()> functionOnRelease = nullptr;
MySlider::MySlider(/*constructor arguments*/)
{
this->preferenceKey = key;
slider->addTouchEventListener([=](Ref* sender, ui::Widget::TouchEventType type)
{
if (type == ui::Widget::TouchEventType::ENDED)
on_release();
});
//... remainder of constructor body
}
void MySlider::set_function_on_release(const std::function<void()>& functionOnRelease)
{
this->functionOnRelease = functionOnRelease;
}
void on_release()
{
if (preferenceKey.empty() == false)
PREFM->set_preference(preferenceKey, slider->getPercent() + min);
if (functionOnRelease)
functionOnRelease();
//the program crashes at this point when the slider gets destroyed
}
}
//The layer in question and the function that creates its slider
void Options::create_font_size_slider()
{
NodeVector sliders;
//there's a static create function convention imposed by the engine
auto fontSizeSlider = MySlider::createWithPreferenceAutomatic("Font Size: ", "FontSizePercentage", 50, 150, false, sliders);
fontSizeSlider->set_function_on_release([=] { this->refresh(); /*this kills the slider*/});
}
编辑2:
我设法通过一个简单而丑陋的黑客来避免崩溃。在稍微延迟(0.05秒)后,我强制刷新()函数在单独的线程上发生。这为所有事情提供了足够的时间,而没有明显的延迟。我可以忍受在设备非常慢和线程调度奇怪的情况下偶然发生的崩溃,因为在崩溃发生之前需要完成的所有事情都要完成。
答案 0 :(得分:0)
您可以通过引用计算对象来解决这个问题(例如COM)。基本上是:
保留()会破坏对象的引用计数。
Release()减少对象的引用计数,如果它现在为零,则删除它。
对象以引用计数1开始生命,并且您从不显式删除引用计数对象(保护析构函数)。
现在,当一个对象想要触发刷新时,它可以先调用自身保留。当控件返回到对象时,它可以调用Release,然后立即返回。对Release的调用可能会删除该对象,但只要它不随后触及其实例数据,这并不重要。
引用计数可以解决很多对象生命周期问题,您可以调用delete (this)
。娱乐时间。另见: