界面库中值得注意的一点就是对象响应事件的时候自身被删除了,那么后续的访问自然就会出问题,所以需要在响应事件之后先添加引用,相关处理之后再查看自身是否已经被删除,如果已经被删除那么就直接退出。juce中通过BailOutChecker来进行这处检查,内部实现很简单也就是通过弱引用来进行,关于弱引用请看上一篇文章
//==============================================================================/** A class to keep an eye on a component and check for it being deleted.This is designed for use with the ListenerList::callChecked() methods, to allowthe list iterator to stop cleanly if the component is deleted by a listener callbackwhile the list is still being iterated.*/class JUCE_API BailOutChecker{public:/** Creates a checker that watches one component. */BailOutChecker (Component* component);/** Returns true if either of the two components have been deleted since this object was created. */bool shouldBailOut() const noexcept;private:const WeakReference<Component> safePointer;JUCE_DECLARE_NON_COPYABLE (BailOutChecker)};
红色部份标识了进行检查的部份:
void Component::internalMouseWheel (MouseInputSource source, Point<float> relativePos,Time time, const MouseWheelDetails& wheel)
{Desktop& desktop = Desktop::getInstance(); BailOutChecker checker (this);const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,this, this, time, relativePos, time, 0, false);if (isCurrentlyBlockedByAnotherModalComponent()){// allow blocked mouse-events to go to global listeners..desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheel);}else{mouseWheelMove (me, wheel); if (checker.shouldBailOut())return;
//历遍的过程中同样需要检查desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheel);if (! checker.shouldBailOut())MouseListenerList::sendWheelEvent (*this, checker, me, wheel);}
}