如何在delphi 7中释放stringlist中的对象? [英] How to free objects in stringlist in delphi 7?

查看:72
本文介绍了如何在delphi 7中释放stringlist中的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是Zarko Gajic在以下文章中释放Delphi的TStrings项目中的对象的想法:在 About.com.delphi 中,我正在使用Delphi 7,TStringList没有OwnsObjects.

Below is the thought of Freeing Objects in Delphi's TStrings Items by Zarko Gajic at at About.com.delphi I am using Delphi 7, TStringList does not have OwnsObjects.

运行以下代码将提示EaccessViolation错误.我不知道为什么以及如何在它周围走动以释放物体.

Running the following code will prompt EaccessViolation error. I donot know why and how to walk around it to free objects.

非常感谢.

procedure TForm6.freelist(const alist: TStringList);
var
  i: integer;
begin
  try
    for i:=0 to pred(alist.Count) do begin
      if Assigned(alist.Objects[i]) then begin
        alist.Objects[i].Free;       
        alist.objects[i]:=nil;       
      end;                           
    end;
    alist.Clear;
  finally
    alist.Free;
  end;
end;

我添加此行 alist.Objects [i]:= Pointer(0); ,并且没有错误.

I add this line, alist.Objects[i]:=Pointer(0); and there is no error.

...

for i:=0 to pred(alist.Count) do begin
          if Assigned(alist.Objects[i]) then begin
            alist.Objects[i]:=Pointer(0);  //newly added line. 
            alist.Objects[i].Free;       
            alist.objects[i]:=nil;       
          end;                           
        end;
...

//But I do not know if this is correct and 
// if the efficiency will be compromised.
//This is awkward method?

推荐答案

下面的原始答案回答了您提出的问题.但是,它表明您没有将对象添加到字符串列表中的注释.您只是将整数转换为 Pointer .在这种情况下,您绝对不能对这些整数调用 Free ,这将完全解释您的错误.因此,问题中的整个代码都是免费的,完成后,您只需在列表中调用 Free .

The original answer below answers the question you asked. However, it transpires in the comments that you are not adding objects to your string list. You are simply adding integers cast to Pointer. In that case you must not call Free on those integers and that would completely explain your error. So the entire code in your question is gratuitous and you should simply call Free on the list when you are done with it.

当将整数强制转换为指针并将其添加到列表中时,除了用于存储指针的内存以外,没有分配的内存.那是因为整数是 value 类型.当您添加真正的指针或对象时,您将添加 reference 类型,并且该对象的处置涉及为对象或 FreeMem 调用 Free (或 Dispose )作为指针.

When you cast an integer to a pointer and add it to the list, there is no memory allocated beyond that used to store the pointer. That is because an integer is a value type. When you add a true pointer or an object then you are adding a reference type and disposal of that object involves calling Free for an object or FreeMem (or Dispose) for a pointer.

问题的原始答案

您的原始代码是正确的,尽管有些笨拙.您遇到的问题在于填充 Objects [] 的代码中.由于我们看不到该代码,因此无法说出您的错误.

Your original code is correct, albeit a little clunky. The problem you have is in the code that populates Objects[]. Since we cannot see that code we can't say what you have got wrong.

现在,说了你的代码很笨拙,这就是我的写法:

Now, having said your code was clunky, here's how I would write it:

procedure ClearList(List: TStringList);
var
  i: Integer;
begin
  for i := 0 to pred(List.Count) do
    List.Objects[i].Free;       
  List.Clear;
end;

上述注意事项

  • You do not need the if Assigned(obj) test before calling obj.Free. I explain why not here: Why should I not use "if Assigned()" before using or freeing things?
  • There's little point in setting the items to nil if you are about to call Clear.
  • You should not call List.Free in such a routine. Your list's life time should be managed separately from the code that clears the list. The call to List.Free should be made in the same scope as the call that constructs the list. Or, if this list is a field of a class, then the call to List.Free should be made from the destructor of the owning class.

现在,正如我在对此问题和您先前的问题的评论中已经说过的那样,使用Delphi 7字符串列表的 Objects [] 属性进行的所有生存期管理工作都非常不令人满意.泄漏物体太容易了.我建议使用以下替代方法:

Now, as I have already said in comments to this question and your previous question, all this lifetime management work with the Objects[] property of a Delphi 7 string list is very unsatisfactory. It's all too easy to leak objects. I would recommend the following alternatives:

  1. 切换到使用 TObjectList 而不是 TStringList .创建列表时,将 OwnsObjects 属性设置为 True .这样可以确保从列表中删除某个项目时,该项目在删除时将被销毁.您只需将清单的项目生命周期管理责任交给清单即可.请注意,这将要求您将存储在当前字符串列表代码中的 string 移为该对象的属性.但这始终是正确的方法,因此我认为这是一种上行而不是缺点.
  2. 如果您希望继续使用字符串列表,请创建一个自己的派生类来处理所有权,方法可能是添加一个名为 OwnsObjects 的属性.将这个问题放在列表上,让您的更高级别的代码不必担心.在列表类的上下文中调试一次代码,然后在知道它起作用的情况下一次又一次地安全重复使用它.
  1. Switch to using TObjectList rather than TStringList. Set the OwnsObjects property to True when you create the list. This will ensure that when an item is deleted from the list, it will be destroyed at the point of removal. You simply hand to the list the responsibility for lifetime management of its items. Note that this will require you to move the string that you are storing in your current string list code to be a property of the object. But that is invariably the correct approach anyway so I see that as an upside rather than a drawback.
  2. If you do wish to keep using a string list, create your own derived class that handles ownership, probably by adding a property named OwnsObjects. Push this problem onto the list and let your higher level code be free from that concern. Debug the code once in the context of the list class and then re-use it over and over again safe and secure in the knowledge that it works.

这篇关于如何在delphi 7中释放stringlist中的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆