Форум: "Основная";
Текущий архив: 2002.01.10;
Скачать: [xml.tar.bz2];
ВнизКак корректно уничтожить из дестрактора компоненты ScrollBar Найти похожие ветки
← →
Aleksandr (2001-12-21 14:33) [0]Компонента имеет ScrollBar, создающийся при ее создании:
constructor TWayTree.Create(AOwner : TComponent);
begin
Inherited;
FScrollBar:=TScrollBar.Create(AOwner);
FScrollBar.Parent:=Parent;
FScrollBar.OnScroll:=FWayTreeScroll;
...
end;
Parent ScrollBar"у я назначаю, чтобы он не мигал и не дергался при перерисовке компоненты (и вообще ей жить не мешал). То есть фактически он не принадлежит компоненте, просто скроллирует ее.
Все прекрасно, но при вызове дестрактора компоненты в этом месте:
if Assigned(FScrollBar) then
FScrollBar.Free
появляется Access Violation at 00000000...
Чего я не так делаю?
← →
Alx2 (2001-12-21 14:39) [1]Может, его кто-то уже перед этим прибил?
← →
Aleksandr (2001-12-21 14:41) [2]Не знаю... Только если этот самый Parent раньше не вышибает СкроллБар, а уж потом компоненту... Только как проверить, если Assigned всего лишь сверяет с nil?
← →
Alx2 (2001-12-21 14:44) [3]Вот-вот...
Тогда просто его не грохай. Это сделает Owner, когда помирать будет (или Parent? - не помню. Но ведь позаботился кто-то уже?).
← →
Alx2 (2001-12-21 14:46) [4]Вдогонку: в конструктор скроллу попробую передавать себя (т.е TWay).
← →
Alx2 (2001-12-21 14:49) [5]Точно!
Вот из help:
property Owner : TComponent;
Indicates the component that is responsible for freeing this component.
← →
Aleksandr (2001-12-21 15:06) [6]Спасибо!
← →
Aleksandr (2001-12-21 15:16) [7]Млин... усе равно Access Violation...
← →
Alx2 (2001-12-21 15:23) [8]Как выглядит код сейчас?
← →
Alx2 (2001-12-21 15:27) [9]Петрушка может сидеть, наверное, в том, что в TWay.Destroy сначала идет inherited, который и грохает скролл. Т.е. заботится уже не о ком.
Можно попробовать для чистоты inherited воткнуть последним, после FScrollBar.Free; FScrollBar:=Nil. И посмотреть где будет AV.
← →
Aleksandr (2001-12-21 15:51) [10]Полностью дестрактор выглядит так:
destructor TWayTree.Destroy;
var
W : TWayItem;
begin
try
if FDestroyItems then begin
while FPoints.Count>0 do begin
W:=TWayItem(FPoints.Items[0]);
FPoints.Delete(0);
W.Free
end
end;
finally
FPoints.Free;
FFont.Free;
if Assigned(FScrollBar) then
FScrollBar.Free;
inherited Destroy
end
end;
Естественно, inherited Destroy вызываю последним...
← →
DieHard (2001-12-21 15:58) [11]Зачем вообще разрушаешь FScrollBar, предоставь это AOwner, кому и положено...
← →
Alx2 (2001-12-21 16:05) [12]Попробуй проверить у TWay свойство ComponentCount
Если 0, то все где-то прибито уже.
← →
Юрий Зотов (2001-12-21 16:06) [13]Происходит следующее. Scrollbar Вы создаете с тем же владельцем, что и владелец Вашего компонента:
FScrollBar:=TScrollBar.Create(AOwner);
Значит, этот AOwner при своем уничтожении будет убивать сначала Ваш компонент, а потом созданный Вами Scrollbar. Но Ваш компонент убивает его в своем деструкторе и поэтому Aowner пытается убить уже убитый Scrollbar. Вот и ошибка.
Создавайте Scrollbar так:
FScrollBar:=TScrollBar.Create(Self);
И после этого можете убивать его в своем деструкторе (а можете и не убивать - он будет убит автоматически).
← →
Alx2 (2001-12-21 16:08) [14]>DieHard
Оно-то понятно. Просто интересно где этот скролл помереть успевает до TWayTree.Destroy, так как Owner у него TWayTree...
← →
Alx2 (2001-12-21 16:11) [15]>Юрий Зотов
Процитирую себя (см. выше):
Вдогонку: в конструктор скроллу попробуй передавать себя (т.е TWaytree).
Сейчас вся беда в выяснении где этот скролл помереть успевает до TWayTree.Destroy, так как Owner у него TWayTree...
← →
Freezer (2001-12-21 16:20) [16]
if not (csDestroying in ComponentState) then
if Assigned(FScrollBar) then
FScrollBar.Free;
inherited Destroy;
← →
Юрий Зотов (2001-12-21 16:22) [17]> Alx2
> где этот скролл помереть успевает до TWayTree.Destroy
Нигде. До TWayTree.Destroy он не умирает. Он умирает именно в TWayTree.Destroy.
> так как Owner у него TWayTree...
Нет. Owner у него ТОТ ЖЕ, что и у TWayTree. В этом и есть ошибка. Сначала его убивает TWayTree, а потом еще и Owner - и вот здесь-то возникает AV. То есть, НЕ в TWayTree.Destroy, а уже ПОСЛЕ.
← →
Alx2 (2001-12-21 16:29) [18]>Юрий Зотов
Ну ладно. Александр нас рассудит. В своих ответах ранее я сделал акцент именно на то, чтобы у скролла Owner был именно TWayTree. Как оно у него стало на самом деле - не знаю. То есть вызов должен быть именно такой, какой написали Вы: FScrollBar:=TScrollBar.Create(Self);
Но то, что ошибка не исчезла - странно. Хотя без исходников сказать мало что можно.
← →
Юрий Зотов (2001-12-21 16:49) [19]> Alx2 © (21.12.01 16:29)
Согласен, нужен код конструктора - тот, который сейчас, а не тот, который уже приводился. Впрочем, подозреваю, что он не изменился, иначе ошибка должна была исчезнуть. Странно, что Aleksandr молчит. Ау-у-у!
← →
Aleksandr (2001-12-21 17:01) [20]Перепробовал варианты в констракторе:
FScrollBar:=TScrollBar.Create(Self);
FScrollBar:=TScrollBar.Create(Owner);
При любом из них в Destroy происходит AV.
← →
Aleksandr (2001-12-21 17:06) [21]Да, кстати, в дестракторе я FScrollBar.Free заменил на FreeAndNil(FScrollBar) - на случай, если AV генерирует Owner.
← →
Юрий Зотов (2001-12-21 17:08) [22]Тогда, видимо, Alx2 прав - надо искать, где убивается Scrollbar. Сделайте так.
1. Проверьте, чтобы в путь отладки были включены исходники VCL.
2. В деструкторе TScrollbar поставьте BreakPoint и запустите программу.
3. Когда придете на BreakPoint, вызовите окно Call Stack и посмотрите, откуда Вы туда пришли. Скорее всего, там и будет причина ошибки.
← →
Aleksandr (2001-12-21 17:34) [23]ОК. А если его вообще не уничтожать в дестракторе, он так и будет память загаживать? Просто формой с этой компонентой юзверы будут пользоваться с такой же частотой, с какой бухгалтер юзает калькулятор...
← →
Юрий Зотов (2001-12-21 20:57) [24]Если его Owner - не nil, то он будет уничтожен вместе с Owner"ом. Но лично я предпочитаю удалять ручками, в деструкторе - как у Вас. Хотя бы потому, что это позволяет вылавливать ситуации, подобные Вашей и указывающие на то, что в программе явно что-то не так. Поэтому очень советую Вам все же раскопать, в чем там дело.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.01.10;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.003 c