Delphi:with-blockの終わりにインターフェイス参照が解放されなくなるのはいつですか?

StackOverflow https://stackoverflow.com/questions/1233773

質問

最近、私が書いた非常に古いコードに起因する問題につまずきました。これは、 with ステートメントで使用されているインターフェース参照が with -ブロックは残っています-暗黙の 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

誰かが古い&quot; with is evil&quot;を開始したときはいつでも議論これは常に私が「はい、しかし...」を続けることを念頭に置いていた1つの例でした。私が間違っていたようです...誰でも確認できますか?

役に立ちましたか?

解決

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

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

他のヒント

この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; 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top