powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Циклические ссылки в модулях классов
9 сообщений из 9, страница 1 из 1
Циклические ссылки в модулях классов
    #32232955
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начитался тут про модули классов и решил еще раз проконсультироваться.

Началось все, собственно, с изменения размеров столбцов ленточной формы.

Есть форма, вешаю на нее класс с обработкой событий MouseMove, MouseClick и пр.

Но она не видит событий, которые происходят у надписей. При инициализации класса для формы в цикле вешаю класс с обработкой аналогичных событий для каждой надписи.

Но из этих обработок надо "видеть" поля формы (и не по имени формы - она может быть открыта несколько раз, - а по ссылке).

Кроме того, чтобы не дублировать текст процедуры обработки событий мыши, из надписей просто вызываю обработку соответствующего события в форме и передаю все аргументы - видимо, классический вариант циклической ссылки.

Пока это работает. Но теперь боюсь.

Вопрос: можно ли обойтись без циклических ссылок (если продублировать код обработки манипуляций мыши для каждой надписи, не будет ли и простое обращение к полям родительской формы для Access'a циклической ссылкой)?

Спасибо.
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32232993
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
+
Если в моей ситуации нельзя, то есть ли способ избежать возможных результатов ее (циклической ссылки) существования (типа Release или др.)?
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235260
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привожу текст, пришедший мне на мыло от Шкуренко Александра.

Здравствуй Георгий.

Увидел в форуме твой вопрос о циклических ссылках. Немного покопался по
своим архивам и вот, что нашел. Почему ответ не в форум, дома отрубили
телефон, а на работе только электронная почта :-(((
Ну да ладно. В общем, проблема эта решаема, с помощью API. (А может, есть
и аналог в VBA).Спасибо ЛОХУ ПОЗОРНОМУ. Он как-то обмолвился про memcpy,
ну я и вел поиски в этом направлении. Но использовать ли ее, я еще для
себя не решил. Если знаешь что такое ссылки на объекты смело можешь
пропускать написанное ниже.

Объектная ссылка это ничто иное, как адрес памяти, который указывает где начинается объект.
Длина его равна 4 байтам. Поэтому по идее можно скопировать адрес.
VB и VBA не позволяют просто - так скопировать этот адрес , но для
этого можно использовать API функцию CopyMemory.
Декларация в C++ выглядит следующим образом.

VOID CopyMemory(PVOID Destination, CONST VOID* Source, SIZE_T Length)

в VBA копирование указателей будет выглядеть следующим образом

Call CopyMemory(objDestination, objSource, 4).

Ура! Все вроде бы хорошо. Но тут выплывают любимые COM объекты, с их функциями AddRef
и Realease. AddRef - вызывается при появлении новой ссылки на объект и увеличивает
значение счетчика. Release - метод вызывается при освобождении ссылки на объект и
уменьшает значение счетчика на 1. Он же удаляет объект из памяти при обнулении
счетчика ссылок. Т.е. когда в VB мы пишем Set obj = Chtoto, для Chtoto
выполняется AddRef, а при уничтожении этой ссылки (Set obj = Nothing) выполняется Release.
Пример:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Sub Test()
        Dim obj1 as cls1
        Dim obj2 as cls2
        Set cls1 = New cls2 ' создался объект, счетчик ссылок = 1
        Call CopyMemory(obj2, obj1, 4) ' обманываем VBA (прикольно VBA - кирилицей МИФ)'
        obj2.AnyMethod
        Set obj2 = Nothing ' выполняется Release, счетчик =  0 , объект уничтожается'
        Set obj1 = Nothing ' здесь происходит крах программы т.к.obj1 указывает на'
                           ' несуществующий объект'
End Sub


Казалось бы не будем писать Set obj2 = Nothing и все OK. Но в этом случае VBA сделает
за нас эту работу сам и опять крах. Чтобы решить эту проблему необходимо знать, как же
VB определяет "жива" та или иная ссылка или нет. В C++ и C ссылка указывающая на ничто
равна 0. Ага. Сделаем и мы тоже самое.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Sub Test()
        Dim obj1 as cls1
        Dim obj2 as cls2
        Dim Nothing_ as Long
        Set cls1 = New cls2 ' создался объект, счетчик ссылок = 1'
        Call CopyMemory(obj2, obj1,  4 ) ' обманываем VBA
        obj2.AnyMethod
        Nothing_ = 0 ' этого можно было и не делать т.к. переменная'
                     ' инициализируется  0 '
        Call CopyMemory(obj2, Nothing_, 4) ' очищаем вручную ссылку, главное'
        Set Obj1 = Nothing ' выполняется Release, счетчик =  0 , объект уничтожается'
End Sub


Вот такие пироги у меня получились. Не знаю, может я что-то упустил из виду.
Хорошо было бы конечно задать этот вопрос ГУРУ Access и VB в форум, но у меня сейчас
с интернетом глухо :-(
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235359
Фотография Лох Позорный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Честно скажу, я такими вещами давно не заморачивался, но очень похоже на правду.
Примерно такое же решение видел в "VB Hardcore" (автора не помню, но рекомендую к прочтению)
Ща придут обладатели полного собрания сочинений Гетца и скажут, что там тоже это есть
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235379
Фотография Senin Viktor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не-а в Гетце этого нет. Хотя я и не полный обладатель его сочинения :)

==
Я щас в яндексе задал поиск по функции CopyMemory - Такую туеву-хучу полезных примеров нашел... разбираться надо неделю
Пойду по очередно функции из win32api.txt искать, опыта набираться // правда думаю вернусь лет так чекрез 20 :)
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235386
(c)VIG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ЛП
Bruce McKinney Hardcore Visual Basic

Not reference counting
Unfortunately, Visual Basic doesn’t have a syntax for creating an uncounted reference. Any reference you create will be counted automatically. Fortunately, there’s a way to immediately decrement that reference as if it never happened. Let’s look at the code for how this is done in the FSearch form. We’ll do this with a very unusual Property Get/Set pair. First let’s look at the internal variable shared by the Get and Set procedures:

‘ Pointer for XEditor referencePrivate pEditor As Long
Behind all the fancy talk, a COM object is nothing more than a pointer, and we’ll have to treat it as a pointer if we want to avoid the normal behavior that is so convenient in most situations but so much in the way for owned objects.

We talked about how the XEditor control creates and initializes an FSearch form in Chapter 9. The key point is that XEditor passes a reference to itself to FSearch with the following line:

Set finddlg.Editor = Me
This calls the Editor Property Set procedure on FSearch. Let’s see how it works:

Friend Property Set Editor(ByVal editorA As XEditor) ‘ Store an Editor pointer rather than an Editor object ‘ No AddRef for storing the pointer pEditor = ObjPtr(editorA)End Property
The undocumented ObjPtr function (introduced with its cousins StrPtr and VarPtr in Chapter 2) returns a dumb pointer rather than a smart object. Dumb is the idea here. The Property Set procedure will be called just once—when FSearch is created. It stores the pointer and every time FSearch needs to use the XEditor instance, it calls the Property Get. That’s where the real magic happens:

Friend Property Get Editor() As XEditor Dim editorI As XEditor ‘ Turn editorI into an illegal, uncounted interface pointer CopyMemory editorI, pEditor, 4 ‘ Do NOT hit the End button here! You will crash! ‘ Assign to legal reference (VB AddRefs it) Set Editor = editorI ‘ Still do NOT hit the End button! You will still crash! ‘ Destroy the illegal reference CopyMemory editorI, 0&, 4 ‘ OK, hit the End button if you must ‘ Internal XEditor reference goes out of scope (VB Releases it)End Property
This looks dangerous—and it is. The whole point is to access XEditor without permanently incrementing its reference count. The local copy editorI will hold the unreferenced copy. The CopyMemory API procedure is used to copy the object pointer to the object, thus bypassing the normal object reference scheme. The editorI object will not have its reference count incremented. If you terminate your program early (by clicking End where I told you not to), Visual Basic will try to destroy the XEditor instance twice—once for the original reference and once for this uncounted reference. The first time it will call Release, which will decrement the reference and, finding a count of 0, destroy the object. The second time it will call Release on an object that no longer exists. Crash!

As long as you don’t try to release it, the illegal reference works fine. You can assign it to a legal reference, such as the return value of the Property Get. What you can’t do is let this illegal reference go out of scope. If you do, Visual Basic will release it, which will destroy the XEditor object, and the next time anyone tries to access XEditor from FSearch or anywhere else—crash! The purpose of the second CopyMemory is to set the illegal reference to Nothing (which happens to be a null pointer) without decreasing its reference count. Visual Basic won’t call Release on Nothing, and editorI won’t cause a crash when it goes out of scope.
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235393
Фотография Лох Позорный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Виктор Сенин
Я имел в виду не "Access Developers Handbook", а его труды по Visual Basic'у собственно.
В adh этого нет, эт точно.
Не заблудись там, в этом Win32api.txt

2 копирайтнутый VIG
Сенькс. Аж ностальгия пробила
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32235404
(c)VIG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Л.П
Меня тоже
...
Рейтинг: 0 / 0
Циклические ссылки в модулях классов
    #32240903
Фотография Geo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ща придут обладатели полного собрания сочинений Гетца и скажут, что там тоже это есть

Да простят меня Гетц сотоварищи, но позволю себе привести кусочек из первого тома Access 2002:
----------
Проблема циклической ссылки состоит в том, что она не позволяет полностью уничтожить объекты. Предположим, вы используете эти объекты в коде:

Dim objInv as Invoice
' При создании объекта Invoice создается и объект Customer

Set objInv = New Invoice
' Здесь код работает с объектом Invoice
Set objInv = Nothing

Присваивая объекту Invoice значение Nothing, разработчик предполагает, что будет выполняться метод Terminate указанного объекта. В данном случае этого не происходит, потому что объект Customer (автоматически формируемый классом Invoice в ходе создания объекта Invoice) все еще содержит ссылку на объект Invoice. Более того, уничтожив связь с объектом Invoice, вы лишаетесь возможности сообщить объекту Customer о том, что нужно освободить объект Invoice.

Проблему можно решить, добавив в объект-владелец специальный метод удаления других указателей на него. Например, к объекту Invoice можно добавить метод Cleanup:

Public Sub Cleanup()
Set Customer.Parent = Nothing
Set Customer.Nothing
End Sub

Столкнувшись с необходимостью избавиться от объекта Invoice, вызовите метод Cleanuo и пресвойте этому объекту значение Nothing:

Dim objInv as Invoice
Set objInv = New Invoice
' Здесь код работает с объектом Invoice
objInv.Cleanup
Set objInv = Nothing
---------------

Вот, собственно. В оправдание перед вышеупомянутыми товарищами, могу лишь еще раз порекомендовать всем, кто еще не является владельцем их собрания сочинений, возможно быстрее исправить это недоразумение :)
И, главное, читать внимательнее! :)
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Циклические ссылки в модулях классов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]