TList TObjectList的区别和使用

所在的单元

TList(Classes.pas)

TObjectList(Contnrs.pas)


TObjectList对象的创建方法有一个参数: constructor TObjectList.Create(AOwnsObjects: Boolean); 从字面就可理解其意义:拥有对象集与否。

帮助文档

If the OwnsObjects property is set to true (the default), TObjectList controls the memory of its objects, freeing an object when its index is reassigned; when it is removed from the list with the Delete, Remove, or Clear method; or when the TObjectList instance is itself destroyed.
这段话的意思就是TObjectList 的几个删除方法和释放方法都受参数AOwnsObjects的影响。 用的默认参数值,释放时ObjectList里的对象一块释放掉.

TOjectList = Class (Tlist);
TOjectList继承Tlist,从名字上看就可以知道它是专门为对象列表制作的,那么他到底丰富了那些功能呢?
首先是 TObject 作为对象可以方便使用,无需指针强制。
丰富了 Notify 针对当前状态处理,比如如果是删除就将该点的引用一并清理掉;

procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
     if (Action = lnDeleted) and OwnsObjects then
        TObject(Ptr).Free;

     inherited Notify(Ptr, Action);
end;

看notify方法会发现:如果TOjectList.OwnsObjects=True时(默认的创建),释放的时候会连里面的对象一块释放掉。  TOjectList.OwnsObjects=False时,释放的时候不会释放里面的对象。
Tlist 中,有 Clear(),将呼叫 SetCount,SetCapacity;即删除所有。

procedure TList.Clear(); 
begin
     SetCount(0);
     SetCapacity(0);
end;

 当该对象销毁时,也会自动调用Clear() 清除所有。

destructor TList.Destroy;
begin
   Clear();
end;

 如果从 Tlist 继承也必须实现 Notify() ,方便资源释放,减少麻烦。 List和OjectList释放的区别如下例子: 

 1 procedure TForm1.Button1Click(Sender: TObject);
 2 var
 3  list: TObjectList;
 4  i: Integer;
 5  btn: TButton;
 6 begin
 7   list := TObjectList.Create;
 8   for i := 0 to 6 do
 9   begin
10      btn := TButton.Create(Self);
11      with btn do begin
12        Caption := Format('Btn %d', [i+1]);
13        Parent := Self;
14      end;
15      list.Add(btn);
16    end;
17    ShowMessage('TObjectList 释放时, 会同时释放其中的对象');
18    list.Free;
19 end; 
20 
21 procedure TForm1.Button2Click(Sender: TObject);
22 var
23   list: TList;
24   i: Integer;
25   btn: TButton;
26 begin
27   list := TList.Create;
28   for i := 0 to 6 do
29   begin
30      btn := TButton.Create(Self);
31      with btn do 
32      begin
33         Caption := Format('Btn %d', [i+1]);
34         Parent := Self; 
35      end;
36      list.Add(btn);
37   end; 
38   ShowMessage('TList 释放后, 其中的对象并未释放');
39   list.Free;
40 end;

如果用TObjectList来存储,当调用sort方法时要注意先将owerobject设置为False

还有一个有意思的类,相信我们都用过TStringList,有一个AddObject方法,可以操作对象,类似TObjectList

总结:如果有一个对象需要用到列表,最好从 TOjectList 开始继承,对资源释放有完善的处理机制。

posted on 2017-07-28 18:14  天军  阅读(1193)  评论(0编辑  收藏  举报

导航