![]() |
Destroy себя - ошибка!
Доброго времени,
Проблема заключается в следующем, пишу для себя компонент, Родителем является TsScrollBox, а дочерними TsPanel (со свойствами alTop). ![]() Дочерние элементы создаю динамически, и присваиваются через "добавленную" к родителю функцию Add. Ошибка заключается в следующем, в каждой строке имеется кнопка "Х" закрыть (удалить строку), При нажатии на нее вызывается встроенное событие doCloseClick, в котором выполняется Free;и переход в destructor: Код:
DestroyComponents; Заметил что если удалить создание дочерних элементов, т.е. оставить только одну кнопку закрыть, то ошибки нету. |
Цитата:
Объёкт уже удалён, соответственно доступ к его полям класса и виртуальным функциям будет вызывать ошибку. А доступ этот, разумеется, производится где-то в нижних уровнях иерархии классов. Если интересно, где именно - установи "исходники VCL" и поищи :) Вообще "самоуничтожение" объектов недопустимо просто потому,*что после вызова деструктора метод объекта будет продолжаться |
что такое FFileStream? как и когда объявлен? поставь перед каждым ...Free код if (...<>0) debug_string('уже удалён'); а после каждого ...=0. В какой последовательности в делфи идёт уничтожение объектов?
к примеру: в с++ сначала вызывается деструктор объекта, потом только всех его составляющих (таким образом на момент видимости они ещё живы) |
pva, видишь ли, у него получается так - вызывается деструктор объекта, объект уничтожается, текущий метод завершается, потом управление передаётся в другие методы уже уничтоженного объекта.
|
а если строчки местами поменять - заработает?
|
pva, разумеется нет - ведь ошибка происходит в базовых классах при обращении к полям уже удалённого объекта
|
Цитата:
|
Цитата:
Не надо так делать. Согласно принципам ООП, правильнее будет следующий способ. Метод doCloseClick скрывает компонент, выставляет значение true логическому свойству "DeleteMe" компонента и завершает работу. Далее вызывается обработчик для события OnIdle (вызывается в моменты "простоя программы"), который перебирает компоненты и удаляет отмеченные. Или можно поступить проще - не удалять закрываемые компоненты, а лишь скрывать их, обнулять свойства и перемещать в конец списка. Ведь всё равно так или иначе потребуется добавлять новые - тогда по команде "Добавить" программа просто отобразит первый из скрытых, а новый компонент создавать будет только при необходимости P.S. Цитата:
Кстати, не мешало бы почитать справку по методу TComponents.DestroyComponents(). Что он делает? Как он работает? Нужно ли вызывать его вручную? Какие проблемы могут возникнуть при его вызове? :) |
в делфи это самое делает TForm.Release. e5620, интерес к теме не пропал ещё?
|
Время: 10:32. |
Время: 10:32.
© OSzone.net 2001-