Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник
Коллекция курьезных вопросов из форумов
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2

Корректо остановить Таймеры в деструкторе.


Саня ©   (26.02.18 15:44

Есть у меня класс, где в качестве полей несколько таймеров, на таймера повешены обработчики методов того же класса.

Уничтожая класс, таймеры видимо все равно еще работают. Могут обратится к уже уничтоженному родительскому классу, получаю AV.

Как мне корректно остановить таймеры и затем уничтожить класс.


DayGaykin ©   (26.02.18 16:01[1]

Free?


Юрий Зотов ©   (26.02.18 16:20[2]

> Как мне корректно остановить таймеры и затем уничтожить класс.

В деструкторе класса сначала уничтожить таймеры, потом вызвать inherited.


Саня ©   (26.02.18 16:22[3]


> В деструкторе класса сначала уничтожить таймеры, потом вызвать
> inherited.

Так и делаю, но нужно наверное какую-то задержку делать.


Юрий Зотов ©   (26.02.18 16:28[4]

Программа однопоточная?


Юрий Зотов ©   (26.02.18 16:35[5]

Еще: проверьте, не вызывается ли из обработчиков таймеров код уничтожения класса? То есть, не пытается ли программа убить объект из его же метода?


Саня ©   (26.02.18 16:35[6]


> Юрий Зотов ©   (26.02.18 16:28) [4]
>
> Программа однопоточная?

Да.
Aдрес AV 00000000, так что вообще не понятно.


Юрий Зотов ©   (26.02.18 16:39[7]

procedure TMyClass.AnyProc;
begin
 ...
 Free;
 ... // Здесь обращение к любому полю класса может дать AV
end;


Саня ©   (26.02.18 16:58[8]

Странно, все должно работать нормально, я только и того, что ради эксперемента
добавил в свой класс одно поле 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.


DayGaykin ©   (26.02.18 17:16[9]

MyTimer := TTimer.Create(Self);
замени на
MyTimer := TTimer.Create(nil);


Саня ©   (26.02.18 17:47[10]


> DayGaykin ©   (26.02.18 17:16) [9]
>
> MyTimer := TTimer.Create(Self);
> замени на
> MyTimer := TTimer.Create(nil);

И Так тоже пробовал.


Саня ©   (26.02.18 17:58[11]

)))

Скопировал проект на  более мощный домашний ПК и не могу добиться ошибки, хотя на том ПК на котором AV ситуация воспроизводится 10 из 10.

Тут точно что-то с таймерами, может быть быстрее тикает на другом ПК или что-то типа того.


> > MyTimer := TTimer.Create(nil);

У меня первоначально так и было, так как класс у меня от TObject. Попробую унаследоваться от от TPanel и сделать наоборт

> MyTimer := TTimer.Create(Self);

Но это завтра только будет доступ до того ПК, сегодня на моем ошибка не вкакую не воспроизводится.


Юрий Зотов ©   (26.02.18 19:14[12]

MyTimer уничтожается дважды:

1. Явно в деструкторе TMyClass.
2. Неявно, вместе со своим владельцем.

Отсюда и ошибка.


Rouse_ ©   (28.02.18 19:24[13]

В Данном коде ошибки нет (не воспроизводится). Кинь экзешник и обязательно MAP файл в архиве, только в этой ситуевине че-то снять можно, а лучше посмотри, мошт у тебя там какие пакеты неявно линкуются?


Rouse_ ©   (28.02.18 19:25[14]

Ну и первым делом есесно MyClass: TMyClass; убери из глобалки, может бы с этим что нам не показываешь, нахомячил


dmk ©   (28.02.18 23:03[15]

В пустой аппликации все норм.


Redmond   (03.03.18 21:14[16]

Для начала вместо
{...}.Free;
всегда использовать
FreeAndNil({...});
Потом, что видно в отладчике? А то тоже не воспроизводится...


Германн ©   (04.03.18 02:41[17]


> Redmond   (03.03.18 21:14) [16]
>
> Для начала вместо
> ?
> 1
>  
> {...}.Free;
>
> всегда использовать
> ?
> 1
>  
> FreeAndNil({...});

Почему и главное зачем?


Игорь Шевченко ©   (04.03.18 10:04[18]

Redmond   (03.03.18 21:14) [16]

http://www.nickhodges.com/post/Using-FreeAndNil.aspx


Rouse_ ©   (04.03.18 14:28[19]

Там же как приговор:
"If your code requires you to use FreeAndNil to reveal and easily find bugs, then your design is wrong." :)


Страницы: 1 2 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо