0

状況:

TDataSetIDを参照として保持する必要があるからビジュアルコンポーネントを作成します。コンポーネントはオブジェクトのみを格納でき、文字列は格納できません。

擬似コード:

for Record in DataSet do
  AddComponent.Data := Record['id']

ここDataで、はタイプTObjectで、idフィールドは文字列タイプ(実際にはGUID)です。

質問:

オブジェクトプロパティに文字列を格納するにはどうすればよいですか?

カスタムタイプを使用するボクシングソリューションを試しましたが、TBox<string>メモリ管理の問題を回避したいと思います。

4

2 に答える 2

2

のタイプがの場合、DataメモリTObject管理の問題を回避することはできません。コンパイラは、TObjectインスタンスの存続期間を管理しません。標準のライフタイム管理メカニズムの1つを使用する必要があります。

  1. try / finalブロック、およびへの明示的な呼び出しを使用して処理しFreeます。
  2. オブジェクトを派生TComponentさせ、ラップされた文字列へのすべての参照よりも長持ちすることが保証されているものによって所有されるようにします。

オプション2にはいくつかのバリエーションがあります。所有権を譲渡する他の方法には、インターフェースの使用が含まれます。所有者がオブジェクトへのすべての参照よりも長持ちする限り、あなたは安全です。

個人的には、オプション2はあまり好きではありません。コンパイラーがオブジェクトの存続期間を管理しない場合は、自分で管理することを好みます。明示的な管理を使用すると、オブジェクトの寿命がいつ終了するかを推論する方が簡単であることがわかります。

于 2013-03-26T10:18:23.807 に答える
0

オブジェクトプロパティに文字列を格納するにはどうすればよいですか?

なんで ?

上手、

  1. sizeof(TObject) = sizeof(Pointer)
  2. Stringは参照カウントタイプであるため、StringRecクラッカータイプを使用してすべての組み込み関数を管理するか、compielr組み込みカウンターを使用します。効果が低く、間接レベルが追加されているにもかかわらず、2番目のアプローチを試してみます。

type StringContainer = record Data: String; end;
     PStringContainer = ^StringContainer;

var p: PStringContainer;

for Record in DataSet do begin
  New(P);
  P^.Data := Record['id'];
  Pointer(AddComponent.Data) := P;
end;

Dispose(...)コンポーネントでこれらのポインタが不要になったときに呼び出すことを忘れないでください。

procedure TMyComponent.BeforeDestruction;
var P: PStringContainer;
begin
    P := Pointer(Data);
    Data := nil;
    Dispose(P); // should free the string, since P type was given
    inherited; 
end;

メモリ管理の問題を避けたい。

正確にどのような種類の問題があり、プログラムのどの部分にありますか?

于 2013-03-26T10:17:10.290 に答える