The LevelWindowManager class contains two maps of type
typedef std::map<unsigned long, BaseProperty::Pointer> ObserverToPropertyMap;
The key parameter (unsigned long) is obtain by calling
it->Value()->GetProperty("...")->AddObserver(...)
where "it" is an iterator of type
mitk::DataStorage::SetOfObjects::ConstIterator
If the SetOfObjects contains more than one element, multiple observers with the same key will be added to the map, as in mitkLevelWindowManager.cpp:288
for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) { if (it->Value().IsNull()) continue; /* register listener for changes in layer property */ itk::ReceptorMemberCommand<LevelWindowManager>::Pointer command2 = itk::ReceptorMemberCommand<LevelWindowManager>::New(); command2->SetCallbackFunction(this, &LevelWindowManager::Update); m_PropObserverToNode2[it->Value()->GetProperty("layer")->AddObserver( itk::ModifiedEvent(), command2)] = it->Value()->GetProperty("layer"); }
The call to the RemoveObserver() method will only remove one and only one observer even if multiple observers have been added
for (ObserverToPropertyMap::iterator iter = m_PropObserverToNode2.begin(); iter != m_PropObserverToNode2.end(); ++iter) { (*iter).second->RemoveObserver((*iter).first); }
Observers might still be registered in the system even after LevelWindowManager object is deleted. Crash will occur if the observed event is emitted and the callback method (here, Update()) is called without existing object.
A fix is to change ObserverToPropertyMap by
typedef std::pair<unsigned long, DataNode::Pointer> PropDataPair; typedef std::map<PropDataPair, BaseProperty::Pointer> ObserverToPropertyMap;
to be sure to have a unique observer identifier for each objects of the SetOfObjects.
I will submit a patch shortly.