7

TComponent の変数を持つユニットがあり、次のようにユニットの初期化でこのコンポーネントを作成します。

var
  XComp: TComponent;
.
.
.
.

initialization
begin
  XCom := TComponent.Create(Application);
end;

ユニットをインストールした後、Delphi を閉じたときに Access Violation エラー メッセージ (EAccessViolation) が表示される

しかし、作成者を次のように変更したとき

initialization
begin
  XCom := TComponent.Create(nil);
end;

すべてうまくいきました...違いを知りたいですか?そして何が良いですか?

注:エラーは、デルファイを閉じるときにのみ表示されます(設計時を意味します)。

ありがとう。

4

2 に答える 2

13

使用するとき

XCom := TComponent.Create(Application);

アプリケーションを XCom の所有者にします。アプリケーションが終了するとき、それが所有者であるため、XCom の破棄を処理します。

あなたがするとき

XCom := TComponent.Create(nil);

XCom の所有者は誰もいないため、アプリケーションが終了したときに自分で解放する必要があります。

XCom を手動で解放した後、アプリケーションが XCom も解放しようとしたため、例外が発生した可能性があります。

于 2012-08-04T11:15:14.090 に答える
2

基本的に両方とも許可されており、次のようなコードがある場合でも AV になることはありません。

MyComp := TMyComp.Create(Application);
try
  {...}
finally
  MyComp.Free;
end;

これは、適切にコーディングされたコンポーネントは、破棄されるときに所有者のコンポーネント リストから削除されるためです。

ここでの問題は、コンポーネントがアプリケーション オブジェクトによって既に解放されており、後でいくつかのコードがそれにアクセスしようとしている可能性があると思います。コードにファイナライズ セクションがあるのではないでしょうか。または、オブジェクトとインターフェイスが混在していて、参照カウントが原因である可能性があります。

問題をデバッグするには、パッケージの「ホスト アプリケーション」を Delphi (C:\Program Files\\BDS\\Bin\bds.exe) に設定して、デバッガで IDE を実行します。コンポーネントのデストラクタにブレークポイントを設定します。そうすれば、ファイルが解放されている場所と、AV が発生している場所を見つけることができます。

于 2012-08-05T10:05:27.973 に答える