Fix crash on destruction of wxDataViewCtrl in wxOSX.

The control remained associated to the model so a dangling pointer could be
used if the model was destroyed after the control.

Fix this by removing the control from the model list of notifiers when it is
destroyed.

Closes #14124.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71511 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2012-05-20 20:29:09 +00:00
parent e779f09357
commit a2c3fc7c75
2 changed files with 18 additions and 1 deletions

View File

@@ -300,6 +300,8 @@ private:
wxDataViewColumnPtrArrayType m_ColumnPtrs; // all column pointers are stored in an array wxDataViewColumnPtrArrayType m_ColumnPtrs; // all column pointers are stored in an array
wxDataViewModelNotifier* m_ModelNotifier; // stores the model notifier for the control (does not own the notifier)
// wxWidget internal stuff: // wxWidget internal stuff:
DECLARE_DYNAMIC_CLASS(wxDataViewCtrl) DECLARE_DYNAMIC_CLASS(wxDataViewCtrl)
DECLARE_NO_COPY_CLASS(wxDataViewCtrl) DECLARE_NO_COPY_CLASS(wxDataViewCtrl)

View File

@@ -348,6 +348,11 @@ void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr)
wxDataViewCtrl::~wxDataViewCtrl() wxDataViewCtrl::~wxDataViewCtrl()
{ {
ClearColumns(); ClearColumns();
// Ensure that the already destructed controls is not notified about changes
// in the model any more.
if (m_ModelNotifier != NULL)
m_ModelNotifier->GetOwner()->RemoveNotifier(m_ModelNotifier);
} }
void wxDataViewCtrl::Init() void wxDataViewCtrl::Init()
@@ -355,6 +360,7 @@ void wxDataViewCtrl::Init()
m_CustomRendererPtr = NULL; m_CustomRendererPtr = NULL;
m_Deleting = false; m_Deleting = false;
m_cgContext = NULL; m_cgContext = NULL;
m_ModelNotifier = NULL;
} }
bool wxDataViewCtrl::Create(wxWindow *parent, bool wxDataViewCtrl::Create(wxWindow *parent,
@@ -381,10 +387,19 @@ bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
wxCHECK_MSG(dataViewWidgetPtr != NULL,false,"Pointer to native control must not be NULL."); wxCHECK_MSG(dataViewWidgetPtr != NULL,false,"Pointer to native control must not be NULL.");
// We could have been associated with another model previously, break the
// association in this case.
if ( m_ModelNotifier )
m_ModelNotifier->GetOwner()->RemoveNotifier(m_ModelNotifier);
if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model)) if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model))
{ {
if (model != NULL) if (model != NULL)
model->AddNotifier(new wxOSXDataViewModelNotifier(this)); {
m_ModelNotifier = new wxOSXDataViewModelNotifier(this);
model->AddNotifier(m_ModelNotifier);
}
return true; return true;
} }
else else