情况:
我从TDataSet
创建可视组件,该组件应将id作为参考。该组件只能存储对象,而不能存储字符串。
伪代码:
for Record in DataSet do
AddComponent.Data := Record['id']
Data
类型为TObject
且id
字段属于字符串类型(实际上是GUID)。
问题:
如何在对象属性中存储字符串?
我尝试过使用自定义类型TBox<string>
的装箱解决方案,但我想避免内存管理问题。
答案 0 :(得分:2)
如果Data
的类型为TObject
,则无法避免内存管理问题。编译器不会为您管理TObject
实例的生命周期。您将不得不使用标准生命周期管理机制之一:
Free
来处理它。TComponent
派生您的对象,并让它由一些保证比您的包装字符串的所有引用更长的东西所拥有。选项2有许多变体。其他交付所有权的方法包括使用接口。只要所有者超过对象的所有引用,那么您就是安全的。
就我个人而言,我不太喜欢选项2.如果编译器不打算管理我的对象的生命周期,我宁愿自己管理它。我发现,如果我使用显式管理,那么更容易推断我的对象的生命何时结束。
答案 1 :(得分:0)
如何在对象属性中存储字符串?
为什么?
好吧,
sizeof(TObject) = sizeof(Pointer)
String
是重新计算的类型,因此您要么使用StringRec
破解者类型并管理所有内在函数,要么使用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;
我想避免内存管理问题。
究竟哪种问题以及该计划的哪个部分?