首页 > 代码库 > Delphi 中的自动释放策略
Delphi 中的自动释放策略
来自万一老师的博客:http://www.cnblogs.com/del/archive/2011/12/21/2295794.html
--------------------------------------------------------------------------------------------------
一、指定 Owner 后, 随 Owner 连带释放:
//uses Vcl.StdCtrls, Vcl.ExtCtrls;var panel: TPanel;procedure TForm1.Button1Click(Sender: TObject);begin panel := TPanel.Create(Self); panel.Parent := Self; with TButton.Create(panel) do //AOwner = panel begin Parent := panel; Caption := ‘New Button‘; end;end;procedure TForm1.Button2Click(Sender: TObject);begin if Assigned(panel) then FreeAndNil(panel); //连带释放以它为 Owner 的对象end;
二、使用接口:
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); end; // IBass = Interface function GetName: string; procedure SetName(const AName: string); property Name: string read GetName write SetName; end; // TBass = class(TInterfacedObject, IBass) private FName: string; protected function GetName: string; procedure SetName(const AName: string); public constructor Create(const AName: string); end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var X: IBass;begin X := TBass.Create(‘WanYi‘); ShowMessage(X.Name); X.Name := ‘万一‘; ShowMessage(X.Name); {X 在此自动释放}end;{ TBass }constructor TBass.Create(const AName: string);begin FName := AName;end;function TBass.GetName: string;begin Result := FName;end;procedure TBass.SetName(const AName: string);begin FName := AName;end;end.
三、使用结构:
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); end; // TBass = record private FName: string; procedure SetName(const AName: string); public constructor Create(const AName: string); property Name: string read FName write SetName; end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var X: TBass;begin X := TBass.Create(‘WanYi‘); ShowMessage(X.Name); X.Name := ‘万一‘; ShowMessage(X.Name); {X 在此自动释放}end;{ TBass }constructor TBass.Create(const AName: string);begin FName := AName;end;procedure TBass.SetName(const AName: string);begin FName := AName;end;end.
四、在 initialization 中建立、在 finalization 中释放:
unit Unit1;interfaceuses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); end;var Form1: TForm1;implementation{$R *.dfm}var List: TStringList;procedure TForm1.Button1Click(Sender: TObject);begin List.Clear; List.Add(‘WanYi‘); ShowMessage(List.Text);end;initialization List := TStringList.Create;finalization List.Free;end.
五、使用动态数组而不是 TList、TStringList 等:
procedure TForm1.Button1Click(Sender: TObject);var arr: Array of string; i: Integer; s: string;begin for i := 0 to 6 do begin SetLength(arr, Length(arr)+1); arr[High(arr)] := StringOfChar(Char(i+65), 3); end; for s in arr do ShowMessage(s);end;procedure TForm1.Button2Click(Sender: TObject);var arr: TArray<string>; i: Integer; s: string;begin for i := 0 to 6 do begin SetLength(arr, Length(arr)+1); arr[High(arr)] := StringOfChar(Char(i+65), 3); end; for s in arr do ShowMessage(s);end;
六、使用 TObjectList 而不是 TList:
uses System.Contnrs;procedure TForm1.Button1Click(Sender: TObject);var list: TObjectList; i: Integer; btn: TButton;begin list := TObjectList.Create; for i := 0 to 6 do begin btn := TButton.Create(Self); with btn do begin Caption := Format(‘Btn %d‘, [i+1]); Parent := Self; Top := Height * i; Left := Width * i div 2; end; list.Add(btn); end; ShowMessage(‘TObjectList 释放时, 会同时释放其中的对象‘); list.Free;end;procedure TForm1.Button2Click(Sender: TObject);var list: TList; i: Integer; btn: TButton;begin list := TList.Create; for i := 0 to 6 do begin btn := TButton.Create(Self); with btn do begin Caption := Format(‘Btn %d‘, [i+1]); Parent := Self; Top := Height * i; Left := Width * i div 2; end; list.Add(btn); end; ShowMessage(‘TList 释放后, 其中的对象并未释放‘); list.Free;end;
七、使用 TObjectList<T> 而不是 TList<T>:
uses System.Generics.Collections;procedure TForm1.Button1Click(Sender: TObject);var list: TObjectList<TButton>; i: Integer; btn: TButton;begin list := TObjectList<TButton>.Create; for i := 0 to 6 do begin btn := TButton.Create(Self); with btn do begin Caption := Format(‘Btn %d‘, [i+1]); Parent := Self; Top := Height * i; Left := Width * i div 2; end; list.Add(btn); end; ShowMessage(‘TObjectList 释放时, 会同时释放其中的对象‘); list.Free;end;procedure TForm1.Button2Click(Sender: TObject);var list: TList<TButton>; i: Integer; btn: TButton;begin list := TList<TButton>.Create; for i := 0 to 6 do begin btn := TButton.Create(Self); with btn do begin Caption := Format(‘Btn %d‘, [i+1]); Parent := Self; Top := Height * i; Left := Width * i div 2; end; list.Add(btn); end; ShowMessage(‘TList 释放后, 其中的对象并未释放‘); list.Free;end;
八、使用结构体而不是结构体指针:
{假如某个函数的参数需要一个结构指针}function Area(rect: PRect): Integer;begin Result := rect.Width * rect.Height;// Result := rect^.Width * rect^.Height;end;{直接声明指针并分配空间后需手动释放}procedure TForm1.Button1Click(Sender: TObject);var P: PRect;begin New(P); P^ := Rect(10, 10, 60, 50); ShowMessage(IntToStr(Area(P))); //2000 Dispose(P);end;{}procedure TForm1.Button2Click(Sender: TObject);var R: TRect;begin R := Rect(10, 10, 60, 50); ShowMessage(IntToStr(Area(@R))); //2000end;
Delphi 中的自动释放策略
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。