ここで少し問題があります。TPersistent クラスを継承するカスタム クラスがあり、このカスタム クラスの内部 (プライベート セクション) には、オーバーライドされた Execute メソッドを使用して (1000 ミリ秒ごとに) 起動するカスタム TThread があります。2つのカスタムクラスを新しいユニットに移動するまで、すべてがうまく機能します...
type
TMyThread= class(TThread)
protected
procedure Execute; override;
end;
TMyClass = class(TPersistent)
private
T: TMyThread;
protected
constructor Create;
public
destructor Destroy; override;
end;
implementation
procedure TMyThread.Execute;
begin
while not Self.Terminated do begin
Sleep(1000);
MessageBox(0, 'test', nil, MB_OK)
end;
end;
constructor TMyClass.Create;
begin
inherited Create;
t := TMyThread.Create(False);
end;
destructor TMyClass.Destroy;
begin
t.Terminate;
t.WaitFor;
FreeAndNil(t);
inherited Destroy;
end;
上記のコードはメイン プロジェクト ユニットではうまく機能しますが、新しいユニットに移動するとスレッド コードが機能しなくなり、TMyClass オブジェクトを解放しようとすると AV が発生します。スレッドがまったく構築されていないと思います。そのため、スレッドを解放しようとすると AV が発生します...しかし、なぜですか? コードがどのユニットにあるかは問題ではありません...
ユニット1:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
p: TMyClass;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
p.Free; //Getting an AV
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
p := TMyClass.Create;
end;
end.
ユニット2:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
TMyClass = class(TPersistent)
private
T: TMyThread;
protected
constructor Create;
public
destructor Destroy; override;
end;
implementation
procedure TMyThread.Execute;
begin
while not Self.Terminated do begin
Sleep(1000);
MessageBox(0, 'test', nil, MB_OK)
end;
end;
constructor TMyClass.Create;
begin
inherited Create;
t := TMyThread.Create(False);
end;
destructor TMyClass.Destroy;
begin
t.Terminate;
t.WaitFor;
FreeAndNil(t);
inherited Destroy;
end;
end.