Форум: "Основная";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];
ВнизОшибка при удалении объектов Найти похожие ветки
← →
TTCustomDelphiMaster (2002-07-16 21:06) [0]Уважаемые коллеги помогите разобраться с ошибкой в программе.
О программе: У некоего объекта (TbaseObj) и его потомков имеется множество визуальных изображений (похожих на TTreeNode, TtreeView, Tlabel и т.д.). Через этот объект осуществляется управление изображениями.
О проблеме: При сворачивании ветви TtreeView происходит массовое удаление визуальных изображений, что в свою очередь приводит массовому к удалению самих объектов (см. procedure TBaseObj.DelVisObj(VisObj: TObject);). В некоторых случаях это приводит к ошибке AV adress 004a7cf2 read of aderess FFFFFFFF ... Какую то закономерность появления этой ошибки определить не удается.
Мне кажется что метод ClearDelList вызывается парралельно несколько раз. Один из них уже удалил DelList[0], а второй пытается обратиться к этому объекту и при этом возникает ошибка.
Ошибку эту удалось побороть установкой временной задержки с использованием таймера (отсюда и появился Sender: Tobject), при этом ClearDelList вызывается только один раз после последнего сообщения WM_ClearDelList. Таймер и все что к нему прилагается я временно вырезал.
Внимание вопросы:
Может ли ClearDelList вызываться Windows или процессором параллельно?
Есть ли идеи как по другому организовать удаление?
← →
TTCustomDelphiMaster (2002-07-16 21:09) [1]Вырезки из программы:
TUniversalList = class
FormHandle: HWND;
Deleting: boolean;
NotVisList: TObjectList;
DelList: TObjectList;
TabMenager: TTableMenager;
DelTimer: TTimer;
constructor CreateHND(FormHND: HWND; TabMen: TTableMenager);
function AddVisObj(VisObj: TObject; Idn: integer; KodType: integer): TBaseObj;
procedure ClearDelList(Sender: TObject);
end;
// Базовый класс
TBaseObj = class
FormHandle: HWND;
DelList: TObjectList;
ParentRange: TObjGrup;
ChildRange: TObjGrup;
Idn: integer;
Num: integer;
KodType: integer;
IdnInfo: integer;
SourceTable: TTable;
InfoTable: TTable;
VisObjList: TObjectList;
// procedure ChangeParam(); virtual; // Изменение свойств объекта
constructor CreateObj(TabMan: TTableMenager; ParentIdn: integer; ParentKodtype: integer); virtual;
constructor HideCreate(TabMan: TTableMenager; Idnobj: integer); virtual;
procedure ShowProperty(); virtual;
procedure DelVisObj(VisObj: TObject);
function GetName(): string;
procedure SetVisObj(com: integer; param: integer);
end;
procedure TUniversalList.ClearDelList(Sender: TObject); // на sender не стоит обращать внимания
begin
if (not Deleting) and (DelList.Count > 5) then
begin
Deleting := True;
while DelList.Count <> 0 do
begin
if ((DelList[0] as TBaseObj).VisObjList.Count = 0) then // здесь останавливается программа при ошибке
begin
NotVisList.Remove(DelList[0]);
DelList.Delete(0);
end
else
begin
DelList.Delete(0);
end;
end;
Deleting := False;
end;
end;
procedure TForm2.WndProc(Var Msg:TMessage);
begin
If Msg.Msg=WM_ClearDelList then
begin
GUnList.ClearDelList(nil);
end;
inherited;
end;
procedure TBaseObj.DelVisObj(VisObj: TObject);
begin
VisObjList.Remove(VisObj);
if VisObjList.Count = 0 then
begin
DelList.Add(Self);
PostMessage(FormHandle, WM_ClearDelList, 0, 0);
end;
end;
← →
TTCustomDelphiMaster (2002-07-16 23:01) [2]Нашел ошибку!!! Да, такую весчь задумал, что все тонкости реализации в одной голове не укладываются. Иногда бывает полезно делать перерывы в работе над проектом. Когда к нему возвращаешься смотришь на него совсем по другому. Вот и в этом проекте неделю искал ошибку, даже какие-то невероятно тупые гипотизы появились, а спустя два месяца сел и за семь минут проблема решена.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];
Память: 0.45 MB
Время: 0.01 c