TObjectList(从TList演变而来)是Delphi中的一个可以叫做container的object。但现在它不存储指针而是存储object,因此你可以在单个item上应用RTTI。这就是说你可以存储各种类型的object并且还可以有效的应用它们。
与TList不同,TObjectList有一个OwnsObjects,OwnsObjects的默认设置为True,这也就是说TObjectList有存储object的内存,因此在往list中存放object的时候就不用担心内存溢出了。当然,你可能不想让TObjectList单独占用内存(比如,你想把一个表格中所有控件都放在TObjectList时)。在这种情况下,你只需把OwnsObjects置为False。
如果你想在前面的代码中使用ObjectList,那么现在我们就用它来查找一个成为Tedit的item,并且用其结构内容作为表格标题。如下:
程序TForm1.btnObjectListClick(Sender: TObject);
var
i: Integer;
ObjectList: TObjectList;
Begin
ObjectList := TObjectList.Create(False); // OwnsObjects = False
Try
ObjectList.Clear;
for i:=0 to Pred(ComponentCount) do
ObjectList.Add(Components[i]);
// Usage of ObjectList...
for i:=0 to Pred(ObjectList.Count) do
if (ObjectList[i] IS TEdit) then
Caption := (ObjectList[i] AS TEdit).Text
Finally
ObjectList.Free
End
end;
注意,这里采用了IS和AS声明方式,这是在RTTI中才可以的。同时也要注意这里采用了结构化设计来保证OwnsObjects置为False从一开始就是正确的。
再往下深入一层就是源于TObjectList的TComponentList。ComponentList和ObjectList的主要区别是ComponentList管理着它的内部成分。当其中一个部分被释放的时候(从外部),ComponentList就会注意到并且通过移除参考并将其打包来自动进行更新。如果你用的是由自身管理或应用的其它部分管理的list部分的话,将会特别有用。
程序TForm1.btnComponentListClick(Sender: TObject);
var
i: Integer;
ComponentList: TComponentList;
Begin
ComponentList := TComponentList.Create(False); // OwnsObjects = False
Try
ComponentList.Clear;
for i:=0 to Pred(ComponentCount) do
ComponentList.Add(Components[i]);
// Removal of Sender from Form (and ComponentList)...
Sender.Free;
// Usage of ObjectList...
Memo1.Lines.Clear;
for i:=0 to Pred(ComponentList.Count) do
if (ComponentList[i] IS TEdit) then
Caption := (ComponentList[i] AS TEdit).Text
Else
Memo1.Lines.Add((ComponentList[i] AS TComponent).Name)
Finally
ComponentList.Free
End
end;