Да, в вашем коде есть ссылочный цикл. Он создается с помощью анонимного метода захвата переменной метода.
Анонимные методы поддерживаются ссылочным подсчетом, сгенерированным компилятором. Любые переменные, захваченные анонимным методом, сохраняются как поля в одном классе. Компилятор создает экземпляр этого класса и сохраняет его в памяти, пока анонимный метод находится в области видимости.
Теперь для создания цикла было бы недостаточно данных. Но тот же экземпляр (тот же класс) будет использоваться для резервного копирования всех анонимных методов в рамках некоторой процедуры.
Переведено на ваш код:
Tree
держитTForm1
Tree
держитCatalog
Catalog
держитTree
Никаких циклов там - Main
не ссылается Catalog
, ни Catalog
ссылкиMain
Но, когда вы смотрите на свою Tree
процедуру, все меняется.
Анонимные методы Event
будут поддерживаться экземпляром скрытого объекта, поэтому давайте посмотрим, что будет там:
- Первый анонимный метод
- Второй анонимный метод
Events
- захвачен вторым анонимным методом
Все еще нет видимых циклов, но затем вы добавляете первый анонимный метод Event
в Tree
список, который удерживается . Чтобы сохранить этот метод в живых, весь поддерживающий объект также будет сохранен.Anonymous method object -> Event -> Tree -> Events -> Event -> Anonymous method object
Tree
Чтобы разорвать этот цикл, вам нужно очистить некоторые ссылки. Например установить , Tree
чтобы nil
где - нибудь в Main
.