Вниз
Скачать: CL | DM;

Удаление ссылок на удаленные компоненты   Найти похожие ветки 

 
far ©   (2004-08-16 18:08) [0]

Доброго времени суток!

Возникла задача:
Компонент A содержит ссылку на компонент B (published свойство типа B). При удалении компонента B с формы возникает опасная ситуация.
Посоветуйте, пожалуйста, как наилучшим образом обнулить битую ссылку. Компоненты A и B могут находиться на разных формах.

Я посмотрел похожие ситуации в VCL:
(TDataSource.DataSet, TDataSet.Connection) -
DataSet хранит набор DataSources, ссылающихся на него,
Connection хранит набор DataSets, ссылающихся на него.

Можно ли обойти подобную практику? (Естественно, не хочется заводить лишний массив в каждом таком случае)


 
афвуд   (2004-08-16 18:32) [1]

Я обходил это более геморройным способом.
Создавал пустой класс от TComponent(далее "простой класс"). ОН умел только при удалении предупредить обьект основного класса, "меня удаляют".
И делал B.InsertComponent(<обьект этого простого класса>).

При удалении того обьекта(B) вызовется деструктор моего простого
класса(ведь каждый TComponent при удалении себя будет сначала удалять своих Components), а он скажет что меня удаляют - и обьект основного класса будет знать, что по этой ссылке удалили компонент.


 
far ©   (2004-08-16 19:01) [2]

Хм... прикольно :)


 
Юрий Зотов ©   (2004-08-16 19:48) [3]

А между тем, в VCL предусмотрен механизм разрешения таких ситуаций. Не обхода, а именно корректного разрешения, причем без всяких дополнительных массивов. Реализуется он замещением метода TA.Notification (а если A и B имеют разных Owner"ов, то еще нужно добавить метод TA.SetB - метод записи свойства B).

Вот схема:

procedure TA.Notification(AComponent: TComponent; Operation: TOperation);
begin
 inherited;
 if (Operation = opRemove) and (AComponent = B) then
   B := nil
end;

procedure TA.SetB(const Value: TB);
begin
 if B <> Value then
 begin
   if B <> nil then
     RemoveFreeNotification(B);
   B := Value;
   if B <> nil then
     FreeNotification(B)
 end
end;


Этот механизм гарантирует, что при любом удалении компонента B свойство A.B автоматически выставится в nil и компонент A перед обращением к B может легко это проверить.

Для примера посмотрите свойство TCustomLabel.FocusControl.


 
far ©   (2004-08-16 20:05) [4]

Super! Спасибо :)

Юрий, а как насчет
http://delphimaster.net/view/5-1092222402/
?

Это слишком специальный вопрос, или слишком глупый? :(


 
Юрий Зотов ©   (2004-08-17 09:38) [5]

> far ©   (16.08.04 20:05) [4]

Вопрос действительно совсем не общий, но вполне нормальный вопрос. Но "с ходу" на него не ответить, надо копаться в недрах VCL, ходить по ним отдадчиком и смотреть, что это за странная фича такая, и как с ней подружиться можно. Ясно, что никто, кроме Вас, заниматься этим не станет.

Включите птичку "Use febug DCUs", перебилдите пакет, набросайте тестовую программку, в ней добавляйте поля нажатием кнопки - и вперед, в отладчик.


 
far ©   (2004-08-17 12:32) [6]


> Юрий Зотов ©   (17.08.04 09:38) [5]

Очень благодарен за внимание. Желаю удачи.



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.46 MB
Время: 0.024 c
3-1120677103
RusLAN_
2005-07-06 23:11
2005.08.14
Проверка правильности SQL-запроса (синтаксиса)


6-1114477934
whiletruedo
2005-04-26 05:12
2005.08.14
вопрос по WebBrowser


9-1114182546
[EViL]
2005-04-22 19:09
2005.08.14
Проблемы с выстрелами, а вернее, с убийством себе подобных.


8-1112783673
DS
2005-04-06 14:34
2005.08.14
Определение разрешения картинок (jpg bmp gif)


14-1122018175
Fin
2005-07-22 11:42
2005.08.14
Что делать или как поступить?




   Наверх