Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 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
8-1112989137
st.andrew
2005-04-08 23:38
2005.08.14
Видеоредактор


4-1118771362
Unknown user
2005-06-14 21:49
2005.08.14
Утечка памяти -помогите!


1-1122400499
ADSWee
2005-07-26 21:54
2005.08.14
string в array[0..259] of char


3-1120805704
kyn66
2005-07-08 10:55
2005.08.14
Переход с RxDBGrid на DBGridEh


14-1122109559
lookin
2005-07-23 13:05
2005.08.14
Что вы получите? Маленький тест.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский