【问题标题】:Passing TObjectList as Parameter - Delphi Xe2将 TObjectList 作为参数传递 - Delphi Xe2
【发布时间】:2013-09-04 01:45:42
【问题描述】:

我有一个“Form 1”,它通过参数将对象列表发送到“Form 2”。但是 Delphi 将列表作为参考发送,所以如果我关闭释放列表中的“Form 1”错误发生在“Form 2”中

作为示例:

表格1:

var list: TObjectList<TPerson>;
    begin

      list  :=  TObjectList<TPerson>.Create();

      Try

      list.Add(TPerson.Create('JOHN', 29));
      list.Add(TPerson.Create('MARK', 27));

      Form2.getList(list);


      Finally
       FreeAndNil(list);
      End;

问题是释放后“Form 1”中的列表引用指向一个已经释放的对象。

问题是:

如何将列表作为副本而不是参考发送到“表格2”?

谢谢!

【问题讨论】:

  • 比你想象的要难。第一步是将TPerson转换为值类型,即记录。一旦你完成了该列表复制就变成了单行。

标签: delphi delphi-xe2


【解决方案1】:

Form2 需要获取列表的所有权并且不让 Form1 释放它,或者循环遍历列表,将内容复制到它自己的本地列表中。

【讨论】:

  • 我认为将变量移到 Form1 的范围之上可能是另一种选择。
【解决方案2】:

考虑到问题的确切表述方式,答案是“不可能”,因为 TObjectList 是一个类,而 Delphi 中的类是引用类型。

实际上,您传递给方法 Form2.getList() 的是一个值,但该值是一个引用,所以它的工作原理非常类似于通过引用传递值。

如果您需要列表的副本,您必须自己做,但是,变量 list 具有对 拥有 项目的列表的引用,因此即使您在 Form2 中创建第二个列表并简单地添加作为参数接收到的列表中存在的那些项目,当列表在 Form1 中销毁时,这些项目将继续被销毁强>。

在你的位置,我将实现我的 Form2.getList 将项目从 Form1 中的列表移动到 Form2 中的列表。像这样的:

procedure TForm2.getList(aPeople: TObjectList<TPerson>);
begin
  while aPeople.Count>0 do
    FPeople.Add(aPeople.Extract(aPeople[0]));
end;

在此代码中,FPeopleTForm2 的数据成员,声明为 TObjectListExtract 方法从列表中删除一个项目而不释放它。因此,在提取后,该项目将被添加到内部列表中。因为它不再在外部列表中,所以当列表存在时它不会被释放。

【讨论】:

  • 没错,您完全理解我的展示位置。我已经编写了像你这样的代码并且它有效!但我想知道是否可以在不循环所有项目的情况下创建列表的副本。我不相信。
【解决方案3】:

检查Tobjectlist的所有权,如果你释放列表并且列表拥有对象,当列表被释放时它会释放列表中的对象。

试试TObjectList&lt;TPerson&gt;.Create(false)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多