0

情况:

TDataSet我从应该保留 id 作为参考的视觉组件创建。组件只能存储对象,不能存储字符串。

伪代码:

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

whereData是类型TObjectid字段是字符串类型(实际上是 GUID)。

问题:

如何在对象属性中存储字符串?

我尝试过使用自定义类型的拳击解决方案TBox<string>,但我想避免内存管理问题。

4

2 回答 2

2

如果类型Data是,TObject那么您将无法避免内存管理问题。编译器不会TObject为您管理实例的生命周期。您将不得不使用标准生命周期管理机制之一:

  1. 您可以使用 try/finally 块来处理它,并显式调用Free.
  2. 您从中派生出您的对象,TComponent并让它由保证比对您包装的字符串的所有引用寿命更长的东西拥有。

选项 2 有许多变体。其他移交所有权的方法包括使用接口。只要所有者比对该对象的所有引用都长,那么您就是安全的。

我个人不太喜欢选项 2。如果编译器不打算管理我的对象的生命周期,我更愿意自己管理它。我发现如果我使用显式管理,那么更容易推断我的对象何时结束。

于 2013-03-26T10:18:23.807 回答
0

如何在对象属性中存储字符串?

为什么 ?

出色地,

  1. sizeof(TObject) = sizeof(Pointer)
  2. String是 ref-counted 类型,所以你要么使用StringReccracker 类型并管理所有内在函数,要么使用 compielr 内置计数器。我会尝试第二种方法,尽管它不太有效并且增加了额外的间接级别。

.

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 回答