-
Есть у меня класс, где в качестве полей несколько таймеров, на таймера повешены обработчики методов того же класса.
Уничтожая класс, таймеры видимо все равно еще работают. Могут обратится к уже уничтоженному родительскому классу, получаю AV.
Как мне корректно остановить таймеры и затем уничтожить класс.
-
Free?
-
> Как мне корректно остановить таймеры и затем уничтожить класс.
В деструкторе класса сначала уничтожить таймеры, потом вызвать inherited.
-
> В деструкторе класса сначала уничтожить таймеры, потом вызвать > inherited.
Так и делаю, но нужно наверное какую-то задержку делать.
-
Программа однопоточная?
-
Еще: проверьте, не вызывается ли из обработчиков таймеров код уничтожения класса? То есть, не пытается ли программа убить объект из его же метода?
-
> Юрий Зотов © (26.02.18 16:28) [4] > > Программа однопоточная?
Да. Aдрес AV 00000000, так что вообще не понятно.
-
procedure TMyClass.AnyProc; begin ... Free; ... // Здесь обращение к любому полю класса может дать AV end;
-
Странно, все должно работать нормально, я только и того, что ради эксперемента добавил в свой класс одно поле TTimer, и повесил пустой обработчик, а вот когда вызываю Timer.Free получаю AV
все же работает, не понятно (:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type TForm1 = class(TForm) Timer1: TTimer; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
TMyClass = class(TPanel) private MyTimer: TTimer; procedure Tick(Sender: TObject); public constructor Create(AOwner: TWinControl); destructor Destroy;override; end;
var Form1: TForm1; MyClass: TMyClass;
implementation
{$R *.dfm}
constructor TMyClass.Create(AOwner: TWinControl); begin inherited Create(AOwner); MyTimer := TTimer.Create(Self); MyTimer.Interval := 300; MyTimer.OnTimer := Tick; end;
destructor TMyClass.Destroy; begin MyTimer.Free; inherited Destroy; end;
procedure TMyClass.Tick(Sender: TObject); begin Randomize; Form1.Caption := IntToStr(Random(1000)); end;
procedure TForm1.FormCreate(Sender: TObject); begin MyClass := TMyClass.Create(Self); MyClass.Parent := Self; end;
procedure TForm1.Button1Click(Sender: TObject); begin MyClass.Free; end;
end.
-
MyTimer := TTimer.Create(Self); замени на MyTimer := TTimer.Create(nil);
-
> DayGaykin © (26.02.18 17:16) [9] > > MyTimer := TTimer.Create(Self); > замени на > MyTimer := TTimer.Create(nil);
И Так тоже пробовал.
-
)))
Скопировал проект на более мощный домашний ПК и не могу добиться ошибки, хотя на том ПК на котором AV ситуация воспроизводится 10 из 10.
Тут точно что-то с таймерами, может быть быстрее тикает на другом ПК или что-то типа того.
> > MyTimer := TTimer.Create(nil);
У меня первоначально так и было, так как класс у меня от TObject. Попробую унаследоваться от от TPanel и сделать наоборт
> MyTimer := TTimer.Create(Self);
Но это завтра только будет доступ до того ПК, сегодня на моем ошибка не вкакую не воспроизводится.
-
MyTimer уничтожается дважды:
1. Явно в деструкторе TMyClass. 2. Неявно, вместе со своим владельцем.
Отсюда и ошибка.
-
В Данном коде ошибки нет (не воспроизводится). Кинь экзешник и обязательно MAP файл в архиве, только в этой ситуевине че-то снять можно, а лучше посмотри, мошт у тебя там какие пакеты неявно линкуются?
-
Ну и первым делом есесно MyClass: TMyClass; убери из глобалки, может бы с этим что нам не показываешь, нахомячил
-
В пустой аппликации все норм.
-
Для начала вместо
{...}.Free; всегда использовать
FreeAndNil({...}); Потом, что видно в отладчике? А то тоже не воспроизводится...
-
> Redmond (03.03.18 21:14) [16] > > Для начала вместо > ? > 1 > > {...}.Free; > > всегда использовать > ? > 1 > > FreeAndNil({...});
Почему и главное зачем?
-
-
Там же как приговор: "If your code requires you to use FreeAndNil to reveal and easily find bugs, then your design is wrong." :)
-
-
> Redmond (05.03.18 15:36) [20] > Палка о двух концах: > http://www.gunsmoker.ru/2009/04/freeandnil-free.html
Странно такие советы читать от Алексея. Ибо он сам вроде как причастен к еуреке. Которую лично я не видел, но уверен, что умеет то, что умеет FastMM - в отладочном режиме загаживать освобожденную память так, что любое обращение к ней вызывает контролируемую ошибку. ---- По сути темы? Ошибку то нашли? Ибо исходный код, на мой взгляд, ошибки не содержит. В т/ч и MyTimer.Free; не является ошибкой.
-
> Redmond (05.03.18 15:36) [20]
Имхо, метод FreeAndNil придуман троешниками для троешников. Понятно мнение АА о том, что лучше использовать именно его, а не метод Free.
|