引用计数TList <t> vs TObjectList <t>

时间:2018-03-05 21:25:19

标签: delphi generics containers

有人能指出我在TList中使用对象接口的教程或最佳实践吗?

我开始实现这个模型,以利用引用计数作为TObjectList的替代(我广泛使用)。虽然我在实现列表时没有遇到任何问题但看起来这样做会增加其他方面的复杂性。

特别是因为列表只保存了一个接口,所以我无法访问类字段(显而易见)。所以我最后乱码“MyInterface as TMyClass”或创建了很多函数来访问字段。是否有一些我不知道的技巧使接口容器更有用?

1 个答案:

答案 0 :(得分:2)

如果您需要访问某些方法,为什么要用接口隐藏它们?接口就是:对其他人可以与该对象进行交互的方式的描述:如果您希望其他类与您的类作为接口对象进行交互,那么这些方法应该是界面。

使用接口作为简化最终化的快捷方式,然后使用强制转换进行黑客攻击会违反整个接口概念,并且还会导致内存泄漏并难以跟踪AV,因为您混合引用的方式:有时接口,有时是TObject。

  

有人能指出我使用对象的教程或最佳实践   TList中的接口?

您的问题与TList无关。所有TList都保留对对象的引用,但它们是设计的 - 它对对象的接口或实现的细节一无所知。您的问题是您没有正确设计类和接口,正如@ArnaudBouchez在评论中指出的那样。

  

我开始实施此模型以利用该参考   计数作为TObjectList的替代品(我广泛使用)

为什么这有必要?为了简化最终确定?默认情况下,TObjectList拥有其对象。 (您还可以设置OwnsObjects属性)。如果您使用的是TObjectList,则无需使用接口来自动清理。您只需要释放TObjectList实例,就像您必须释放TList一样。除非您因特定原因需要接口,否则使用Objects和TObjectList可能更可取,因为与接口相反,您的终结是确定性的。

来自XE帮助:

  

创建TObjectList实例。

     

这个重载方法创建了一个TObjectList实例。

     

OwnsObjects参数是一个指示对象是否的布尔值   条目归列表所有。如果对象是拥有的,则何时进入   从列表中删除,该对象被释放。 OwnsObjects   property是根据此参数的值设置的。默认值为true。

当您释放TObjectList时,在OwnObjects=True时也会释放对象。
请参阅: Clear a TList or a TObjectList (accepted answer there)

知道:通常情况下,您作为Delphi开发人员没有理由参与引用计数的详细信息。如果您觉得需要这样做,那么您的设计在基础层面上就会出现问题。引用计数在TInterfacedObject中实现,并且透明地工作。所有Delphi接口对象都应该从TInterfacedObject(或其兄弟或派生类之一)派生,如下所示:

interface
...

type

IMyInterface=interface (IUnknown)
[GUID]
 function GetValue:integer;
end;

TMyInterface=class(TInterfacedObject,IMyInterface)
 protected
   function GetValue:integer;
end;

implementation
...


TMyInterface.GetValue:integer;
begin
  result := fValue;
end;

end.

然后像这样使用它:

procedure useValue;
var im:IMyInterface;
    x:integer;
begin
 im:=TMyInterface.create;
 x:=im.GetValue;
 showMessage(inttstr(x));
end;

useValue返回时,im被清除 - 您无需做任何事情或担心引用计数。 TInterfacedObject负责所有这些。

请注意,在useValue中,您将引用声明为IMyInterface但是为TMyInterface调用类构造函数 - 这就是您必须初始化接口的方式 - 接口没有构造函数。但是,由于您的引用类型为IMyInterface,因此编译器会对其进行处理 - 只有通过IMyInterface公开的方法才可以访问