Форум: "Компоненты";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];
ВнизУдаление ссылок на удаленные компоненты Найти похожие ветки
← →
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 вся ветка
Форум: "Компоненты";
Текущий архив: 2005.08.14;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.011 c