From a2c3fc7c750c0ac1452d34dcdd9be9c6fcc64c90 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 20 May 2012 20:29:09 +0000 Subject: [PATCH] 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 --- include/wx/osx/dataview.h | 2 ++ src/osx/dataview_osx.cpp | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/wx/osx/dataview.h b/include/wx/osx/dataview.h index b8463c4c99..618a3c2558 100644 --- a/include/wx/osx/dataview.h +++ b/include/wx/osx/dataview.h @@ -300,6 +300,8 @@ private: 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: DECLARE_DYNAMIC_CLASS(wxDataViewCtrl) DECLARE_NO_COPY_CLASS(wxDataViewCtrl) diff --git a/src/osx/dataview_osx.cpp b/src/osx/dataview_osx.cpp index 05ad19fcbe..fd5d37e765 100644 --- a/src/osx/dataview_osx.cpp +++ b/src/osx/dataview_osx.cpp @@ -348,6 +348,11 @@ void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr) wxDataViewCtrl::~wxDataViewCtrl() { 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() @@ -355,6 +360,7 @@ void wxDataViewCtrl::Init() m_CustomRendererPtr = NULL; m_Deleting = false; m_cgContext = NULL; + m_ModelNotifier = NULL; } 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."); + + // 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 (model != NULL) - model->AddNotifier(new wxOSXDataViewModelNotifier(this)); + { + m_ModelNotifier = new wxOSXDataViewModelNotifier(this); + model->AddNotifier(m_ModelNotifier); + } return true; } else -- 2.45.2