首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 2009 泛型容器進階:TObjectList<T> 等物件擁有權管理機制詳解

     編輯:Delphi

為什麼需要 TObjectList<T> 系列?

Delphi 2009 引入泛型容器 Generics.Collections 後,提供了成對的容器類別:

  • 基礎版:TList<T>、TQueue<T>、TStack<T>、TDictionary<TKey,TValue>
  • 物件擁有版:TObjectList<T>、TObjectQueue<T>、TObjectStack<T>、TObjectDictionary<TKey,TValue>

這設計呼應了舊版 Classes.TList 與 Contnrs.TObjectList 的關係:當元素為物件時,「物件擁有版」容器在刪除元素或銷毀容器時,會自動釋放物件實例;基礎版則僅移除參考,不負責釋放記憶體。

實戰驗證:按鈕物件生命週期管理

執行效果動畫

核心程式碼

uses Generics.Collections;

var
  List: TList<TButton>;       // 基礎版:不管理物件生命週期
  ObjList: TObjectList<TButton>; // 物件擁有版:自動釋放物件

procedure TForm1.FormCreate(Sender: TObject);
begin
  List := TList<TButton>.Create;
  ObjList := TObjectList<TButton>.Create;
  // ... 介面初始化略 ...
end;

procedure TForm1.Button1Click(Sender: TObject); // 加入 TList
var btn: TButton;
begin
  btn := TButton.Create(Self);
  btn.Caption := 'TList 中的 Button';
  btn.Parent := Panel1;
  List.Add(btn);
end;

procedure TForm1.Button2Click(Sender: TObject); // 從 TList 移除
begin
  List.RemoveAt(0); // 僅移除參考,Button 物件仍存在於 Panel1 上
end;

procedure TForm1.Button3Click(Sender: TObject); // 加入 TObjectList
var btn: TButton;
begin
  btn := TButton.Create(Self);
  btn.Caption := 'TObjectList 中的 Button';
  btn.Parent := Panel2;
  ObjList.Add(btn);
end;

procedure TForm1.Button4Click(Sender: TObject); // 從 TObjectList 移除
begin
  ObjList.RemoveAt(0); // 自動呼叫 btn.Free,Button 從 Panel2 消失
end;

關鍵行為差異對照表

操作TList<TButton>TObjectList<TButton>
Add(btn)保存參考保存參考,取得擁有權
RemoveAt(0)移除參考,物件存活移除參考,自動 Free 物件
Clear清空列表,物件全殘留清空列表,全數 Free 物件
容器 Free釋放容器本身,元素物件不受影響釋放容器,連帶釋放所有元素物件

原始碼層面解析

TObjectList<T> 繼承自 TList<T>,核心差異在於重寫 Notify 方法:

procedure TObjectList<T>Notify(const Item: T; Action: TCollectionNotification);
begin
  inherited;
  if Action = cnRemoved then
    TObject(Item).Free; // 關鍵:移除時自動釋放
end;

最佳實務建議

  • 使用 TObjectList<T>:容器為物件「唯一擁有者」,生命週期綁定
  • 使用 TList<T>:物件由外部管理、或同時存在多個容器中
  • 避免混用:同一物件實例勿同時加入擁有版與非擁有版容器
  • 設定 OwnsObjects:舊版 TObjectList.Create(False) 可關閉擁有權,但泛型版 無此選項,行為固定為擁有

總結

泛型容器的「雙軌制」設計精準對應記憶體管理需求:TObjectList<T> 系列透過編譯期型別檢查與執行期自動釋放,消除了手動 Free 的遺漏風險,是 Delphi 2009+ 管理物件集合的首選方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved