Эта ссылка вызывает утечку памяти? - PullRequest
2 голосов
/ 06 декабря 2011

У меня есть TabControl, и каждая вкладка содержит TradeBookSetViewModel.Поскольку Tradebook может вырасти довольно большим, пользователь может при необходимости удалить книгу.

В DeleteBook () я просто удаляю TradeBookSetViewModel из наблюдаемой коллекции:

_bookSetViewModels.Remove(oldbook);

Затем я создаюновую пустую книгу в качестве заполнителя и вставьте ее в ту же позицию вкладки.Вкладка по-прежнему выглядит так, как будто она удерживает tradeBook, но на самом деле она пуста.

Для этого я разрешаю новый экземпляр из контейнера Unity и копирую DisplayName из старой книги в пустую книгу.

BookSetViewModel emptyBook = _container.Resolve<BookSetViewModel>();
emptyBook.DisplayName = oldbook.DisplayName;
_bookSetViewModels.Insert(positionOfDisposedTab, emptyBook);

Пока все хорошо.

Но позже я понял, что для emptyBook также требуется свойство Books.Свойство Books относится к типу Dictionary<string, CustomClassItem> Следовательно, сначала я подумал, что могу сделать то же самое, что и с DisplayName.

emptyBook.Books = oldbook.Books;

Но не значит ли это, что emptyBook будет ссылаться на oldBookи, следовательно, oldBook больше не может быть сборщиком мусора?

Может быть, я просто должен вместо этого клонировать словарь:

emptyBook.Books = book.Books.ToDictionary(entry => entry.Key, entry => entry.Value);

Цель: В концемне нужно, чтобы свойство Books в emptyBook не было нулевым, и все же oldBook могла бы собирать мусор.Есть мысли?

Ответы [ 4 ]

1 голос
/ 06 декабря 2011

Если нет прямой или косвенной ссылки из вашего словаря обратно на класс модели представления, тогда проблем не будет.

emptyBook и oldBook просто будут ссылаться на один и тот же словарь, но исходящие ссылки не будутt остановить сборку мусора, только входящие соединения делают это.

1 голос
/ 06 декабря 2011

Но не может ли это означать, что emptyBook будет ссылаться на oldBook, и, следовательно, oldBook больше не будет собирать мусор?

Нет, если только вы не упомянули что-то еще.

Все, что у вас есть, это два объекта (emptyBook и oldbook), которые относятся к одному и тому же Books словарю. Это не создает никаких ссылочных отношений между ними; у каждого нет возможности узнать о другом.

До тех пор, пока oldbook недоступен из root через другую ссылку, он будет иметь право на сборку мусора.

0 голосов
/ 06 декабря 2011

Book и словарь, на который указывает книга, являются двумя независимыми объектами.Один просто ссылается на другой.

Ссылка на поле или свойство класса не создает ссылку на класс, содержащий это поле или свойство.

Если вы храните ссылку наoldbook.DisplayName, вы храните ссылку на объект словаря.Вы не сохраняете ссылку на объект Book, на который указывает oldbook.

Когда запускается сборщик мусора, он увидит, что вы ссылаетесь на словарь, и не соберет его.Он увидит, что вы не ссылаетесь на Book, и соберет его.

Это, конечно, предполагает, что вы на самом деле не ссылаетесь на объект Book где-либо еще.Если ни у одного класса нет объекта, который oldbook упоминается как свойство или поле, и вы удалили его из любых контейнеров, или контейнер, содержащий Book, больше не ссылается, тогда он будет собран.

0 голосов
/ 06 декабря 2011

В дополнение я бы сказал, что «красота» TabControl, что пользователь может работать всегда только с одной вкладкой .Рассмотрим один View Model с несколькими Models сзади.На основании Tab выбран всегда один и тот же View Model выбор из коллекции модели правильный Tradebook.На Tab selection changed View Model назначается активной вкладке.

...