Существует несколько проблем, связанных с управлением памятью в VB6.
Первыми являются круговые ссылки, где дочерний класс указывает на родителя и наоборот. Без явной установки ссылки на Nothing, это иногда относится к формам, а особенно к диалогу, который является редактором для объекта Target. Снова убедившись, что все, что ни к чему, решит проблему.
Основополагающими принципами являются: 1) Если что-либо, на которое указывает объект, является «живым», то это не будет собирать мусор. Поэтому, когда вы устанавливаете ссылку на родительский объект круглой ссылки, ребенок жив, поэтому родитель не получает сбор мусора, так как родитель все еще жив, ребенок не получает собранный мусор.
То же самое с формами. Если вы не установили свойство Target в диалоговом окне, которое ничего не редактирует, он не будет запускать финальную серию событий до тех пор, пока объект цели жив.
Наиболее распространенными побочными эффектами этого являются то, что ваше приложение не будет закрываться должным образом, а объем вашей памяти увеличится дольше, чем приложение будет использоваться.
Что касается утечек GDI, в любое время вы используете внешнюю DLL, которая использует ручки, указатели. Вы ставите себя в ту же область, что и C++ для этих функций. Таким образом, вы должны следить за тем, чтобы вы соблюдали все правила конкретного API или DLL, которые вы используете, что часто подразумевает явное уничтожение того, что вы создали после того, как вы сделали с ним.
Существует элегантное решение для круглого задания. Вместо того, чтобы ребенок ссылался на родителя напрямую, вы используете прокси.
Сначала создайте класс прокси для родительского объекта.
Option Explicit Public Event GetRef(ByRef RHS As MyObject)
Public Function GetMyObject() As MyObject
Dim Ref As MyObject
RaiseEvent GetRef(Ref)
Set GetMyObject = Ref
End Function
Затем определяют приватную переменную в Родитель
Private WithEvents MyProxy As MyObjectProxy
Private Sub Class_Initialize()
Set MyProxy = New MyObjectProxy
End Sub
Тогда настройки только для чтения свойство называется Proxy и реализовать событие GetRef.
Public Property Get Proxy() As MyObjectProxy
Set Proxy = MyProxy
End Property
Private Sub MyProxy_GetRef(RHS As MyObject)
Set RHS = Me
End Sub
Для ребенка или чего-либо еще, для которого требуется ссылка, код выглядит следующим образом.
Private ParentProxy As MyObjectProxy
Public Property Get Parent() As MyObject
If ParentProxy Is Nothing Then
Set Parent = Nothing
Else
Set Parent = ParentProxy.GetRef
End If
End Property
Public Property Set Parent(RHS As MyObject)
If RHS Is Me Then
Set MyObjectProxy = Nothing
ElseIf Target Is Nothing Then
Set MyObjectProxy = Nothing
Else
Set MyObjectProxy = RHS.Proxy
End If
End Property
Поскольку механизм событий не устанавливает ссылку или увеличивает COM счетчика ссылок на объект либо он избегает всего проблемы циклических ссылок, которая является бичом многих VB6 программистов.
Примечание. Источник, из которого я получил его, назвал его прокси, но, благодаря комментарию Энтони, я считаю, что он также подходит для определения шаблона посредника. Он использует определенную функцию VB6 Centric; API событий, который не совсем в духе шаблона посредника.
понимает также, что рамки .NET имеют эквиваленты API Event VB6 в хотя реализуются по-разному (делегаты, и т.д.)
Это известно как шаблон посредника, который стоит добавить к тексту этого ответа. – AnthonyWJones 2008-11-06 10:20:43