Delphi 中的自动释放策略
2017-01-31 15:45
190 查看
来自万一老师的博客:http://www.cnblogs.com/del/archive/2011/12/21/2295794.html
--------------------------------------------------------------------------------------------------
一、指定 Owner 后, 随 Owner 连带释放:
二、使用接口:
三、使用结构:
四、在 initialization 中建立、在 finalization 中释放:
五、使用动态数组而不是 TList、TStringList 等:
六、使用 TObjectList 而不是 TList:
七、使用 TObjectList<T> 而不是 TList<T>:
八、使用结构体而不是结构体指针:
--------------------------------------------------------------------------------------------------
一、指定 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; interface uses 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; interface uses 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; interface uses 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))); //2000 end;
相关文章推荐
- Delphi 中的自动释放策略
- Delphi 中的自动释放策略-转
- Delphi 中的自动释放策略
- Delphi越来越多自动释放的类型,到底是简单还是复杂了?
- 不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针
- Qt的内存释放策略(内存自动释放机制)
- Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)
- Qt的内存释放策略(内存自动释放机制)
- 变量自动释放
- 有关自动释放池的内存堆积问题
- Qt关闭窗体自动释放资源
- 自动释放系统资源 /自动释放资源
- 深入理解Objective-C: Autorelease Pool (自动释放池)
- NSAutoreleasePool自动释放池
- Delphi中如何使Label固定宽度且自动换行
- 如何让delphi在启动时不自动创建空的工程?
- Hibernate与TopLink在主键自动生成策略上的差异
- 自动释放系统资源
- 函数内定义非静态局部变量当函数运行结束后自动释放
- 对于Delphi 5 数据库应用中ODBC数据源的自动管理