Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 1b2255c

Browse files
authored
Merge pull request #9017 from mono/jstedfast-debugger-remove-items-before-dispose
[Debugger] Don't Dispose() items until *after* we call RemoveItems()
2 parents 992faa9 + 7d0aa26 commit 1b2255c

File tree

1 file changed

+101
-88
lines changed

1 file changed

+101
-88
lines changed

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeViewDataSource.cs

Lines changed: 101 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,28 @@ void Insert (MacObjectValueNode parent, int index, ObjectValueNode node)
9696
Add (value, new LoadingObjectValueNode (node));
9797
}
9898

99-
void Remove (MacObjectValueNode node)
99+
void Remove (MacObjectValueNode node, List<MacObjectValueNode> removed)
100100
{
101101
foreach (var child in node.Children)
102-
Remove (child);
102+
Remove (child, removed);
103103

104104
mapping.Remove (node.Target);
105105
node.Children.Clear ();
106-
node.Dispose ();
106+
removed.Add (node);
107+
}
108+
109+
void RestoreExpandedState (ObjectValueNode node)
110+
{
111+
if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint (node)) {
112+
if (TryGetValue (node, out var item))
113+
treeView.ExpandItem (item);
114+
}
115+
}
116+
117+
void RestoreExpandedState (IEnumerable<ObjectValueNode> nodes)
118+
{
119+
foreach (var node in nodes)
120+
RestoreExpandedState (node);
107121
}
108122

109123
public void Replace (ObjectValueNode node, ObjectValueNode[] replacementNodes)
@@ -127,41 +141,40 @@ public void Replace (ObjectValueNode node, ObjectValueNode[] replacementNodes)
127141
if (index == -1)
128142
return;
129143

144+
var removed = new List<MacObjectValueNode> ();
130145
parent.Children.RemoveAt (index);
131-
mapping.Remove (item.Target);
132-
item.Dispose ();
146+
Remove (item, removed);
133147

134148
treeView.BeginUpdates ();
135149

136-
var indexes = new NSIndexSet (index);
150+
try {
151+
var indexes = new NSIndexSet (index);
137152

138-
if (parent.Target is RootObjectValueNode)
139-
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
140-
else
141-
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
153+
if (parent.Target is RootObjectValueNode)
154+
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
155+
else
156+
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
142157

143-
if (replacementNodes.Length > 0) {
144-
for (int i = 0; i < replacementNodes.Length; i++)
145-
Insert (parent, index + i, replacementNodes [i]);
158+
if (replacementNodes.Length > 0) {
159+
for (int i = 0; i < replacementNodes.Length; i++)
160+
Insert (parent, index + i, replacementNodes[i]);
146161

147-
var range = new NSRange (index, replacementNodes.Length);
148-
indexes = NSIndexSet.FromNSRange (range);
162+
var range = new NSRange (index, replacementNodes.Length);
163+
indexes = NSIndexSet.FromNSRange (range);
149164

150-
if (parent.Target is RootObjectValueNode)
151-
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
152-
else
153-
treeView.InsertItems (indexes, parent, NSTableViewAnimation.None);
165+
if (parent.Target is RootObjectValueNode)
166+
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
167+
else
168+
treeView.InsertItems (indexes, parent, NSTableViewAnimation.None);
154169

155-
foreach (var n in replacementNodes) {
156-
if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint (n)) {
157-
if (TryGetValue (n, out MacObjectValueNode x)) {
158-
treeView.ExpandItem (x);
159-
}
160-
}
170+
RestoreExpandedState (replacementNodes);
161171
}
172+
} finally {
173+
treeView.EndUpdates ();
162174
}
163175

164-
treeView.EndUpdates ();
176+
for (int i = 0; i < removed.Count; i++)
177+
removed[i].Dispose ();
165178
}
166179

167180
public void ReloadChildren (ObjectValueNode node)
@@ -171,59 +184,55 @@ public void ReloadChildren (ObjectValueNode node)
171184

172185
treeView.BeginUpdates ();
173186

174-
NSIndexSet indexes;
175-
NSRange range;
187+
try {
188+
NSIndexSet indexes;
189+
NSRange range;
176190

177-
if (parent.Children.Count > 0) {
178-
range = new NSRange (0, parent.Children.Count);
179-
indexes = NSIndexSet.FromNSRange (range);
191+
if (parent.Children.Count > 0) {
192+
range = new NSRange (0, parent.Children.Count);
193+
indexes = NSIndexSet.FromNSRange (range);
180194

181-
foreach (var child in parent.Children) {
182-
mapping.Remove (child.Target);
183-
child.Dispose ();
184-
}
195+
var removed = new List<MacObjectValueNode> ();
196+
foreach (var child in parent.Children)
197+
Remove (child, removed);
185198

186-
parent.Children.Clear ();
199+
parent.Children.Clear ();
187200

188-
if (parent.Target is RootObjectValueNode)
189-
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
190-
else
191-
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
192-
}
201+
if (parent.Target is RootObjectValueNode)
202+
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
203+
else
204+
treeView.RemoveItems (indexes, parent, NSTableViewAnimation.None);
205+
206+
for (int i = 0; i < removed.Count; i++)
207+
removed[i].Dispose ();
208+
}
193209

194-
for (int i = 0; i < node.Children.Count; i++)
195-
Add (parent, node.Children[i]);
210+
for (int i = 0; i < node.Children.Count; i++)
211+
Add (parent, node.Children[i]);
196212

197-
// if we did not load all the children, add a Show More node
198-
if (!node.ChildrenLoaded)
199-
Add (parent, new ShowMoreValuesObjectValueNode (node));
213+
// if we did not load all the children, add a Show More node
214+
if (!node.ChildrenLoaded)
215+
Add (parent, new ShowMoreValuesObjectValueNode (node));
200216

201-
range = new NSRange (0, parent.Children.Count);
202-
indexes = NSIndexSet.FromNSRange (range);
217+
range = new NSRange (0, parent.Children.Count);
218+
indexes = NSIndexSet.FromNSRange (range);
203219

204-
if (parent.Target is RootObjectValueNode)
205-
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
206-
else
207-
treeView.InsertItems (indexes, parent, NSTableViewAnimation.None);
208-
209-
// if we loaded children and discovered that the node does not actually have any children,
210-
// update the node and reload the data.
211-
// TOOD: it would be nice to know this before the node is expanded so we don't see the "loading" node flash
212-
if (!node.HasChildren) {
213-
treeView.ReloadItem (parent);
214-
} else {
215-
// expand any items that we loaded that were expanded previously
216-
217-
foreach (var n in node.Children) {
218-
if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint (n)) {
219-
if (TryGetValue (n, out MacObjectValueNode x)) {
220-
treeView.ExpandItem (x);
221-
}
222-
}
220+
if (parent.Target is RootObjectValueNode)
221+
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
222+
else
223+
treeView.InsertItems (indexes, parent, NSTableViewAnimation.None);
224+
225+
// if we loaded children and discovered that the node does not actually have any children,
226+
// update the node and reload the data.
227+
// TOOD: it would be nice to know this before the node is expanded so we don't see the "loading" node flash
228+
if (!node.HasChildren) {
229+
treeView.ReloadItem (parent);
230+
} else {
231+
RestoreExpandedState (node.Children);
223232
}
233+
} finally {
234+
treeView.EndUpdates ();
224235
}
225-
226-
treeView.EndUpdates ();
227236
}
228237

229238
public void Clear ()
@@ -233,19 +242,23 @@ public void Clear ()
233242
if (AllowWatchExpressions)
234243
count--;
235244

245+
if (count <= 0)
246+
return;
247+
248+
var removed = new List<MacObjectValueNode> ();
236249
for (int i = count - 1; i >= 0; i--) {
237250
var child = Root.Children[i];
238251
Root.Children.RemoveAt (i);
239-
Remove (child);
252+
Remove (child, removed);
240253
}
241254

242-
if (count <= 0)
243-
return;
244-
245255
var range = new NSRange (0, count);
246256
var indexes = NSIndexSet.FromNSRange (range);
247257

248258
treeView.RemoveItems (indexes, null, NSTableViewAnimation.None);
259+
260+
for (int i = 0; i < removed.Count; i++)
261+
removed[i].Dispose ();
249262
}
250263

251264
public void Append (ObjectValueNode node)
@@ -262,14 +275,15 @@ public void Append (ObjectValueNode node)
262275
Add (Root, node);
263276
}
264277

265-
var indexes = NSIndexSet.FromIndex (index);
278+
treeView.BeginUpdates ();
266279

267-
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
280+
try {
281+
var indexes = NSIndexSet.FromIndex (index);
268282

269-
if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint (node)) {
270-
if (TryGetValue(node, out MacObjectValueNode x)) {
271-
treeView.ExpandItem (x);
272-
}
283+
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
284+
RestoreExpandedState (node.Children);
285+
} finally {
286+
treeView.EndUpdates ();
273287
}
274288
}
275289

@@ -287,17 +301,16 @@ public void Append (IList<ObjectValueNode> nodes)
287301
Add (Root, nodes[i]);
288302
}
289303

290-
var range = new NSRange (index, nodes.Count);
291-
var indexes = NSIndexSet.FromNSRange (range);
304+
treeView.BeginUpdates ();
292305

293-
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
306+
try {
307+
var range = new NSRange (index, nodes.Count);
308+
var indexes = NSIndexSet.FromNSRange (range);
294309

295-
foreach (var node in nodes) {
296-
if (treeView.Controller.GetNodeWasExpandedAtLastCheckpoint (node)) {
297-
if (TryGetValue (node, out MacObjectValueNode x)) {
298-
treeView.ExpandItem (x);
299-
}
300-
}
310+
treeView.InsertItems (indexes, null, NSTableViewAnimation.None);
311+
RestoreExpandedState (nodes);
312+
} finally {
313+
treeView.EndUpdates ();
301314
}
302315
}
303316

0 commit comments

Comments
 (0)