2013-10-12 9 views
5

クラスデストラクターが呼び出されたときに解放する必要があるオブジェクトを格納するために、クラス変数内の動的配列を使用すると機能しません。クラスデストラクターが呼び出される前にスコープから外れるDelphiクラス変数

配列はスコープ外になり、クラスデストラクタが呼び出される前に既に破棄されているようです。 これは仕様ですか? XE5で試験

例:

type 
    TLeakingObject = class 
    public 
    I : Integer; 
    end; 

    TTheLeakOwner = class 
    public 
    class var OutofScopeArray:array of TLeakingObject; 
    procedure Add; 
    class destructor Destroy; 
    end; 

procedure TestThis; 
var LeakingTest : TTheLeakOwner; 
begin 
    LeakingTest := TTheLeakOwner.Create; 
    try 
    LeakingTest.Add; 
    finally 
    LeakingTest.DisposeOf; 
    end; 
end; 

{ TTheLeakOwner } 

procedure TTheLeakOwner.Add; 
begin 
    setlength(OutofScopeArray, length(OutofScopeArray) + 1); 
    OutofScopeArray[length(OutofScopeArray) - 1] := TLeakingObject.Create; 
end; 

class destructor TTheLeakOwner.Destroy; 
var I: Integer; 
begin 
    // Length(OutofScopeArray) always = 0, gone out of scope before class destructor ?? 
    for I := 0 to Length(OutofScopeArray) - 1 do 
    FreeAndNil(OutofScopeArray[i]); 
end; 
+0

ない答えが、いくつかのアドバイス:使用しない

はおそらく、エンバカデロから誰かが他の方法でのラウンドは、モバイルプラットフォーム上で特にARCで、絶対にクールではないことをついに実現しましたオブジェクトの配列はTObjectList (generics.collections)ですが、リストが有効範囲外になったときにオブジェクトを解放します。 – whosrdaddy

+0

はい、私は知っていますが、このリークはオープンソースのスレッドプールライブラリで発生します。そのため、この言語で意図されているかどうかを知りたがっています。 – jong

+0

心配する必要はありません、varsはクラスデストラクタの前にきれいにされています、私の答えを参照してください – whosrdaddy

答えて

5

クラスデストラクタは、単位ファイナライズ後に呼び出されるので、これはアレイがもはやクラスデストラクタが呼び出された時に存在することを意味しません。ユニットの最終化では、すべての管理対象変数がRTLによってクリーンアップされます。結局、それは本当に漏れではないので問題ではありません。

アレン・バウアーは、クラス・コンストラクター/デストラクタhereについていくつかの情報を提供しています。

EDIT

は、どうやらこれはdesign

+0

この情報をありがとう、私はこれをTObjectlistに変更します。 – jong

1

によってすでに修正されているこの "デザイン" です。 Delphi 10 Seattleは、皆さん(私も含めて)が期待しているように振る舞います。つまり、クラスのデストラクタの後で参照カウントのクラス変数を解放します。 D

参照:https://quality.embarcadero.com/browse/RSP-11289

関連する問題