![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удаление ссылок на удаленные компоненты [D7]
far © (2004-08-16 18:08:00)Доброго времени суток!
Возникла задача:
Компонент A содержит ссылку на компонент B (published свойство типа B). При удалении компонента B с формы возникает опасная ситуация.
Посоветуйте, пожалуйста, как наилучшим образом обнулить битую ссылку. Компоненты A и B могут находиться на разных формах.
Я посмотрел похожие ситуации в VCL:
(TDataSource.DataSet, TDataSet.Connection) -
DataSet хранит набор DataSources, ссылающихся на него,
Connection хранит набор DataSets, ссылающихся на него.
Можно ли обойти подобную практику? (Естественно, не хочется заводить лишний массив в каждом таком случае)
far (2004-08-17 12:32:00) [1]
> Юрий Зотов © (17.08.04 09:38) [5]
Очень благодарен за внимание. Желаю удачи.
Юрий Зотов (2004-08-17 09:38:00) [2]> far © (16.08.04 20:05) [4]
Вопрос действительно совсем не общий, но вполне нормальный вопрос. Но "с ходу" на него не ответить, надо копаться в недрах VCL, ходить по ним отдадчиком и смотреть, что это за странная фича такая, и как с ней подружиться можно. Ясно, что никто, кроме Вас, заниматься этим не станет.
Включите птичку "Use febug DCUs", перебилдите пакет, набросайте тестовую программку, в ней добавляйте поля нажатием кнопки - и вперед, в отладчик.
far (2004-08-16 20:05:00) [3]Super! Спасибо :)
Юрий, а как насчет
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1092222402&n=12
?
Это слишком специальный вопрос, или слишком глупый? :(
Юрий Зотов (2004-08-16 19:48:00) [4]А между тем, в 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 19:01:00) [5]Хм... прикольно :)
афвуд (2004-08-16 18:32:00) [6]Я обходил это более геморройным способом.
Создавал пустой класс от TComponent(далее "простой класс"). ОН умел только при удалении предупредить обьект основного класса, "меня удаляют".
И делал B.InsertComponent(<обьект этого простого класса>).
При удалении того обьекта(B) вызовется деструктор моего простого
класса(ведь каждый TComponent при удалении себя будет сначала удалять своих Components), а он скажет что меня удаляют - и обьект основного класса будет знать, что по этой ссылке удалили компонент.