1

考虑一个简单的 TMyObject 类,它包含一个字符串数组 [0..9](描述)和一些其他属性(本示例省略)。在某个时刻,我想从 FMyList (TList<TMyObject>) 中删除所有“空”对象(即所有 10 个字符串都是空的)。为此,我将 Pack 方法与 IsEmpty 函数一起使用:

FMyList.Pack(
  function(const MyObject1, MyObject2: TMyObject): boolean
  var
    ii: Integer;
  begin
    result := true;
    for ii := 0 to 9 do
      if (MyObject1.Description[ii] <> '') then
      begin
        result := false;
        break;
      end;
  end);

最初我(错误地)假设 Pack 也会释放(释放)这些对象。事实并非如此,因此上述代码会导致内存泄漏,从而使移除的 TMyObjects “悬空”。

不幸的是,Pack 上的文档有点稀疏。如何正确使用这个方法,保证一个Pack之后,不仅对象从TList中被移除,而且对象也被正确释放?

4

1 回答 1

4

Pack专门用于从列表中删除与数据类型相关的空项。这就是为什么它不会触发任何 OnChange 事件,因为它在技术上不会删除项目,而只是删除后备数组中的空槽。

func的重载IsEmpty并不意味着“从适用于这个和那个的列表中删除所有项目”。

对于您使用的任务来说,这Pack并不是解决方案。您将不得不使用向后循环和Delete. 使用TObjectList<T>withOwnsObjects = True时会自动销毁对象。否则你需要自己做。

编辑:为了完整起见,仅提及这一点-但我建议不要这样做:您仍然可以在返回时提供的 func.Free中的项目。但是恕我直言,该代码有点臭。IsEmptyTrue

于 2021-07-06T13:07:19.427 回答