Показать полную графическую версию : Destroy себя - ошибка!
Доброго времени,
Проблема заключается в следующем, пишу для себя компонент, Родителем является TsScrollBox, а дочерними TsPanel (со свойствами alTop).
http://img413.imageshack.us/img413/8399/123ez.png
Дочерние элементы создаю динамически, и присваиваются через "добавленную" к родителю функцию Add.
Ошибка заключается в следующем, в каждой строке имеется кнопка "Х" закрыть (удалить строку), При нажатии на нее вызывается встроенное событие doCloseClick, в котором выполняется Free;и переход в destructor:
DestroyComponents;
FFileStream.Free;
inherited Destroy;
после этого осуществляется возврат к концу doCloseClick и "ОШИБКА" доступа к памяти по адресу 0х00000030.
Заметил что если удалить создание дочерних элементов, т.е. оставить только одну кнопку закрыть, то ошибки нету.
El Scorpio
01-03-2010, 06:26
после этого осуществляется возврат к концу doCloseClick и "ОШИБКА" доступа к памяти по адресу 0х00000030. »
Всё правильно.
Объёкт уже удалён, соответственно доступ к его полям класса и виртуальным функциям будет вызывать ошибку.
А доступ этот, разумеется, производится где-то в нижних уровнях иерархии классов. Если интересно, где именно - установи "исходники VCL" и поищи :)
Вообще "самоуничтожение" объектов недопустимо просто потому,*что после вызова деструктора метод объекта будет продолжаться
что такое FFileStream? как и когда объявлен? поставь перед каждым ...Free код if (...<>0) debug_string('уже удалён'); а после каждого ...=0. В какой последовательности в делфи идёт уничтожение объектов?
к примеру: в с++ сначала вызывается деструктор объекта, потом только всех его составляющих (таким образом на момент видимости они ещё живы)
El Scorpio
02-03-2010, 05:43
pva, видишь ли, у него получается так - вызывается деструктор объекта, объект уничтожается, текущий метод завершается, потом управление передаётся в другие методы уже уничтоженного объекта.
а если строчки местами поменять - заработает?
El Scorpio
03-03-2010, 05:04
pva, разумеется нет - ведь ошибка происходит в базовых классах при обращении к полям уже удалённого объекта
Ошибка заключается в следующем, в каждой строке имеется кнопка "Х" закрыть (удалить строку), При нажатии на нее вызывается встроенное событие doCloseClick, в котором выполняется Free;и переход в destructor:
Код:
DestroyComponents;
FFileStream.Free;
inherited Destroy; »
это код деструктора? а doCloseClick можно посмотреть?
El Scorpio
04-03-2010, 05:04
Ошибка заключается в следующем, в каждой строке имеется кнопка "Х" закрыть (удалить строку), При нажатии на нее вызывается встроенное событие doCloseClick, в котором выполняется Free;и переход в destructor »
А*после завершения деструктора происходит возвращение в метод doCloseClick удалённого компонента,*из него - в метод doClick удалённой кнопки "Закрыть" :)
Не надо так делать. Согласно принципам ООП, правильнее будет следующий способ.
Метод doCloseClick скрывает компонент, выставляет значение true логическому свойству "DeleteMe" компонента и завершает работу.
Далее вызывается обработчик для события OnIdle (вызывается в моменты "простоя программы"), который перебирает компоненты и удаляет отмеченные.
Или можно поступить проще - не удалять закрываемые компоненты, а лишь скрывать их, обнулять свойства и перемещать в конец списка. Ведь всё равно так или иначе потребуется добавлять новые - тогда по команде "Добавить" программа просто отобразит первый из скрытых, а новый компонент создавать будет только при необходимости
P.S.
Заметил что если удалить создание дочерних элементов, т.е. оставить только одну кнопку закрыть, то ошибки нету. »
Возможно, потому что удаление дочерних элементов (адреса которых перечисляются в списке Components) производится автоматически в деструкторе класса TComponents
Кстати, не мешало бы почитать справку по методу TComponents.DestroyComponents().
Что он делает? Как он работает? Нужно ли вызывать его вручную? Какие проблемы могут возникнуть при его вызове? :)
в делфи это самое делает TForm.Release. e5620, интерес к теме не пропал ещё?
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.