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