1

私の情報源では、次のような構造をよく見かけて使用しています。

with TSQLDataSet.Create(nil) do try
  //Dosomething, get a result from a query.    
finally
  Free;
end;

しかし、私はよく次のような構造も目にします。

with TSQLDataSet.Create(nil) do begin
  //Dosomething, get a result from a query.    
end;

with 構造でオブジェクトを作成する場合、それらを解放する必要がありますか、それとも with ブロックの最後で自動的に行われますか?

4

3 に答える 3

8

オブジェクトを手動で解放する必要があります。ブロックの最後で自動的に解放されるというのは正しくありません。これは一般的にwith適用されます。に何か特別なものがあるかどうかはわかりません。TSQLDataSet

于 2012-09-28T15:02:48.847 に答える
8

する必要がありfreeます。

Class.Createは単なる式であるため、Delphi は結果の値がどの式から来たのかを知ることができません。

VCL ソースを読むことができます - 常に明示的.Freeです。

そして、非オブジェクトの例を考えることができます:

var r: record .... end;
with r do begin
...
end;

Delphi がwith最後にすべてを解放しようとした場合、free非オブジェクト化を試みますか?

with SomeObjectFactory.GetMeAnObject do begin
...
end;

ここでは、コンストラクターではなく、関数によってオブジェクトを作成します。そして、この関数はTLabel.Fontまたはと違いはありませんTDataSet.FieldByName。ここでDelphifreeを使用する必要がありますか?

危険な当て推量を避けて均一に保つことwithは、まさにwith. それは単なるエイリアスです。これ以上何もない。Using(x){..}これは 1974 年に設計されたもので、最新の .Net/Scalaコンストラクトの機能を複製するものではありません。


あなたがおそらく見たのは次のような構造でした

with TForm.Create(Application) do ...;
with TLabel.Create(MainForm.Panel1) do ...;

これは非常に異なります。新しく作成されたコントロールを所有者に属するものとして挿入します。所有者は、それ自体が dのfree場合、所有するすべてのコンポーネントになります。freeしかし、それは使用しませんCreate(nil)。そして、それがまだ行われている場合、withブロック内で明示的な呼び出しが表示され、オブジェクトがコンテナー/親にバインドされます (ただし、 と バインディングの間の例外の場合は非常に脆弱です.Create)。

于 2012-09-28T15:04:44.843 に答える
0

Delphi (Object pascal)、C、C++、およびマネージ コードではないその他の多くの第 3 世代言語では、メモリをリサイクルする責任がプログラマに与えられます。したがって、どちらの場合でも、獲得したメモリがコードのどこかで割り当て解除されていることを確認する必要があります。

あなたが与えた最初の例は、作成したオブジェクトが end ステートメントの後に生きている必要がないことを前提としています。2 番目の例では、オブジェクトが作成され、End ステートメントの後に使用される別のオブジェクトに渡されることを前提としています。したがって、using オブジェクトはメモリの割り当て解除を処理する必要があります。

Java VM や .Net アプリケーションなどのマネージド コード環境では、メモリは環境によって処理されます。環境は、割り当てられたメモリ ピースへの参照がないことを感知し、環境に適しているときはいつでもそれを解放します。

于 2012-09-29T06:03:57.903 に答える