4

私は最近、私が書いたいくつかの非常に古いコードによって引き起こされた問題に出くわしました。これは明らかに、withステートメントで使用されているインターフェイス参照が -blockwithを離れるとすぐに解放されると想定していました - 暗黙の -block のようなものですtry-finally(C# のusing-statementに似ています)。私が正しく理解していれば)。

どうやら (Delphi 2009 では) これは (もはや?) そうではありません。これがいつ起こったのか知っている人はいますか?それとも、私のコードはそもそも間違っていたのでしょうか?

明確にするために、簡単な例を次に示します。

type
  IMyIntf = interface;
  TSomeObject = class(TInterfacedObject, IMyIntf)
  protected
    constructor Create; override; // creates some sort of context
    destructor Destroy; override; // cleans up the context created in Create
  public
    class function GetMyIntf: IMyIntf; //a factory method, calling the constructor
  end;

procedure TestIt;
begin
  DoSomething;
  with (TSomeObject.GetMyIntf) do
    begin
      DoStuff;
      DoMoreStuff;
    end; // <- expected: TSomeObject gets destroyed because its ref.count is decreased to 0
  DoSomethingElse;
end; // <- this is where TSomeObject.Destroy actually gets called

誰かが古い「with悪である」という議論を始めたときはいつでも、これは常に私が心に留めていた 1 つの例であり、「はい、でも...」と言い続けました。私が間違っていたようです...誰か確認できますか?

4

2 に答える 2

17

Pascal/Delphiのwith保存された単語は、レコードまたはオブジェクト/クラスのメンバーに簡単にアクセスするためにのみ使用されます (つまり、レコード/オブジェクト/クラスの名前を言及しないため)。withガベージ コレクションに関連するC# とは大きく異なります。recordsこれは、多くのデータ メンバー (当時は単に「フィールド」と呼ばれていました) へのコード呼び出しを簡素化するために、Pascal 言語の誕生以来存在しています。

要約withすると、ガベージ コレクション、メモリの解放、またはオブジェクト インスタンスの破棄とは関係ありません。ヘッダーで構築されたオブジェクトは、with以前は別のコード行で初期化されていた可能性がありますが、それは同じです。

于 2009-08-05T15:06:39.037 に答える
3

この WITH 動作は変更されていません。期待される動作に到達するには、次の方法でコードを変更できます。

    procedure TestIt;
    var
       myIntf: IMyIntf; 
    begin
      DoSomething;

      myIntf := TSomeObject.GetMyIntf
      DoStuff;
      DoMoreStuff;
      myIntf := nil; // <- here is where TSomeObject.Destroy called

      DoSomethingElse;
    end; 

または、次の手順で実行できます。

procedure TestIt;

   procedure DoAllStuff;
   var
      myIntf: IMyIntf; 
   begin
      myIntf := TSomeObject.GetMyIntf
      DoStuff;
      DoMoreStuff;
   end;  // <- here is where TSomeObject.Destroy called

begin    
  DoSomething;
  DoAllStuff;
  DoSomethingElse;
end; 
于 2009-08-05T18:50:54.990 に答える