Удаление объекта vb6 - удивительная проблема - PullRequest
0 голосов
/ 06 мая 2020

Я «изобрел» технику связанного списка в vb6, поместив указатель внутри объекта:

Class FooBar:
Public ptr As FooBar

Теперь я просто держу указатель на заголовок списка внутри Head.ptr точек к следующему объекту, Head.ptr.ptr указывает на следующий объект, et c.

Когда я хочу уничтожить список, я просто использую Set Head = Nothing, это приводит к очистке Head.ptr, который, в свою очередь, запускает очистку Head.ptr.ptr et c, в результате чего получается пустой список (я фактически проверил его, поставив точку останова в событии Class_Terminate).

Это работает красиво и аккуратно, пока мне не понравится 10 000 объектов в списке. Теперь строка Set Head = Nothing приводит к ошибке «Out of stack memory», после которой IDE cra sh.

Оказывается, vb6 рекурсивно очищает объект (это происходит, даже если у меня нет событие Class_Terminate).

Итак, я подумал, что должен уничтожить список «вручную», с каким-то l oop. но я не мог придумать, как это сделать, так как использование указателя в l oop и установка его на Nothing не делает ... ничего, поскольку он AddRef для объекта!

Что мне делать ???

Ответы [ 2 ]

1 голос
/ 06 мая 2020
• 1000 объект.
Class FooBar:
Public ptr As FooBar

Public Function SafeRemove() As FooBar
Set SafeRemove = ptr
Set ptr = Nothing
End Function

В модуле:

Sub ClearList()
While Head Is Nothing = False
    Set Head = Head.SafeRemove
Wend
End Sub
0 голосов
/ 06 мая 2020

Я могу понять, почему вы получаете переполнение стека. Вы неявно вызываете метод Release () интерфейса IUnknown, который вызывает внутренний метод уничтожения VB, который очищает все внутреннее состояние, включая переменную, которая указывает на следующий элемент, который затем вызывает Release (), et c., et c.

Чтобы обойти проблему переполнения стека, вам лучше реализовать двусвязный список и всегда сохранять указатель в конец списка. Но тогда у вас возникнет проблема с круговыми ссылками, и ничего не исчезнет, ​​если у вас не будет специального c метода удаления.

С таким же успехом вы можете использовать объект VBA.Collection, о котором мне сказали (в книге Hardcore Visual Basi c это двусвязный список внутри).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...