将字符串存储在TObject类型的属性中的最轻量级方法是什么?

时间:2013-03-26 10:08:47

标签: string delphi delphi-xe2 boxing

情况:

我从TDataSet创建可视组件,该组件应将id作为参考。该组件只能存储对象,而不能存储字符串。

伪代码:

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

Data类型为TObjectid字段属于字符串类型(实际上是GUID)。

问题:

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

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

2 个答案:

答案 0 :(得分:2)

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

  1. 您可以使用try / finally块和显式调用Free来处理它。
  2. 您从TComponent派生您的对象,并让它由一些保证比您的包装字符串的所有引用更长的东西所拥有。
  3. 选项2有许多变体。其他交付所有权的方法包括使用接口。只要所有者超过对象的所有引用,那么您就是安全的。

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

答案 1 :(得分:0)

  

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

为什么?

好吧,

  1. sizeof(TObject) = sizeof(Pointer)
  2. String是重新计算的类型,因此您要么使用StringRec破解者类型并管理所有内在函数,要么使用compielr内置计数器。我尝试了第二种方法,尽管效果较差,并增加了额外的间接级别。
  3. 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;
    
      

    我想避免内存管理问题。

    究竟哪种问题以及该计划的哪个部分?