Delphi 是否需要释放GetEnumerator返回的枚举数?

Delphi 是否需要释放GetEnumerator返回的枚举数?,delphi,collections,enumerator,Delphi,Collections,Enumerator,我想用Delphi XE2为泛型集合使用枚举器。我想知道是谁拥有函数GetEnumerator返回的TEnumerator(我在文档中没有找到任何明确的答案): 我是否拥有它并需要在使用后释放它 或者它是收藏所有的,而我不必关心发布它 代码: 程序测试; 变量 我的字典:t字典; myEnum:TDictionary.TPairEnumerator; 开始 {创建字典} myDictionary:=TDictionary.Create; Add('Key1','Value 1'); Add(

我想用Delphi XE2为泛型集合使用枚举器。我想知道是谁拥有函数GetEnumerator返回的TEnumerator(我在文档中没有找到任何明确的答案):

  • 我是否拥有它并需要在使用后释放它
  • 或者它是收藏所有的,而我不必关心发布它
代码:

程序测试;
变量
我的字典:t字典;
myEnum:TDictionary.TPairEnumerator;
开始
{创建字典}
myDictionary:=TDictionary.Create;
Add('Key1','Value 1');
Add('Key2','Value 2');
{使用枚举数}
myEnum:=myDictionary.GetEnumerator;
// ... 用枚举器做点什么。。。
{释放对象}
myEnum.Free;//**我需要释放枚举器吗**
我的字典。免费;
结束;

如果查看TDictionary的源代码,您会发现GetEnumerator(在其祖先中)调用DoGetEnumerator,而DoGetEnumerator在TDictionary中调用重新引入的GetEnumerator版本

重新引入的TDictionary.GetEnumerator创建一个TPairEnumerator实例,将自身作为要枚举的字典传递。字典中没有对TPairEnumerator的引用。PairEnumerator没有收到其字典被销毁的通知


因此,是的,您确实需要自己释放枚举器,并且为了避免任何访问冲突,您确实应该在销毁它枚举的字典之前这样做。

您还可以通过在项目源中的开始后添加“ReportMemoryLeaksOnShutdown:=True”作为第一行来测试这一点,通过这种方式,您可以测试各种其他泄漏。@DorinDuminica:=True如果不是第一个,也可以line@mjn谢谢,我忘了编辑它,在写了上面的评论之后,我在某个地方(不记得了)读到,在代码的任何部分更改标志都可以,但是把它放在“容易访问”的地方仍然是个好主意无需在文件中搜索…在使用
for in
循环的情况下,我们没有对枚举器的引用(它是隐藏的);Delphi自己释放了它吗?@teran:是的,编译器添加了必要的魔法来释放隐藏的枚举数。@Uwerabe,是的,我刚刚检查:)我真的认为
for in
循环将枚举数存储为
IEnumerable
(我假设它创建了新的对象,它支持
IEnumerable
并拥有我们的枚举器对象,因此它在循环结束时销毁了我们的枚举器。因此,Embarcadero建议实现IEnumerable以使容器可枚举-)我更改了示例中的发布顺序,使其现在的顺序与您建议的相同!
procedure Test;
var
  myDictionary: TDictionary<String, String>;
  myEnum: TDictionary<String, String>.TPairEnumerator;
begin
  { Create a dictionary }
  myDictionary := TDictionary<String, String>.Create;
  myDictionary.Add('Key1', 'Value 1');
  myDictionary.Add('Key2', 'Value 2');

  { Use an enumerator }
  myEnum := myDictionary.GetEnumerator;
  // ... do something with the Enumerator ...

  { Release objects }
  myEnum.Free; // ** Do I need to free the enumerator? **
  myDictionary.Free;          
end;