]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix crash on destruction of wxDataViewCtrl in wxOSX.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 May 2012 20:29:09 +0000 (20:29 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 May 2012 20:29:09 +0000 (20:29 +0000)
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
src/osx/dataview_osx.cpp

index b8463c4c991cf12a13bafb6bf2b135ffdf10bbf3..618a3c255835ad03a1555dcac565006cb8392559 100644 (file)
@@ -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)
index 05ad19fcbee1e03fb45b255f550b36e71590bb2c..fd5d37e76526560b5ef3063107b252b5265f7ea4 100644 (file)
@@ -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