Delphi 中的自动释放策略-转
八、使用结构体而不是结构体指针: 很重要
一、指定 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 := to do
begin
SetLength(arr, Length(arr)+);
arr[High(arr)] := StringOfChar(Char(i+), );
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 := to do
begin
SetLength(arr, Length(arr)+);
arr[High(arr)] := StringOfChar(Char(i+), );
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 := to do
begin
btn := TButton.Create(Self);
with btn do begin
Caption := Format('Btn %d', [i+]);
Parent := Self;
Top := Height * i;
Left := Width * i div ;
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 := to do
begin
btn := TButton.Create(Self);
with btn do begin
Caption := Format('Btn %d', [i+]);
Parent := Self;
Top := Height * i;
Left := Width * i div ;
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 := to do
begin
btn := TButton.Create(Self);
with btn do begin
Caption := Format('Btn %d', [i+]);
Parent := Self;
Top := Height * i;
Left := Width * i div ;
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 := to do
begin
btn := TButton.Create(Self);
with btn do begin
Caption := Format('Btn %d', [i+]);
Parent := Self;
Top := Height * i;
Left := Width * i div ;
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(, , , );
ShowMessage(IntToStr(Area(P))); //
Dispose(P);
end;
{}
procedure TForm1.Button2Click(Sender: TObject);
var
R: TRect;
begin
R := Rect(, , , );
ShowMessage(IntToStr(Area(@R))); //
end;
Delphi 中的自动释放策略-转的更多相关文章
- Delphi 中的自动释放策略
来自万一老师的博客:http://www.cnblogs.com/del/archive/2011/12/21/2295794.html ------------------------------- ...
- Delphi中关于资源释放(Free,Relealse,FreeAndNil)
根据日常编程经验,得出一些Delphi中关于资源释放的体会. 假如有对象Obj为TObject类型: 1) Obj.Free直接释放资源后,调用OnDestroy事件,但是没有将Obj指针值置为Nil ...
- 简单说说Delphi中线程的释放
线程的释放方式有两种:一种是线程在运行完成后自动释放,一种是手动释放. 无论是那种释放,都应该在线程停止后进行释放. 然而线程的停止也有两种情况:一种是不需要设置标志位,直接完成:一种是由于execu ...
- Objective-C中的自动释放池
自动释放池块@autoreleasepool 自动释放池块在MRC和ARC下都可以使用.在MARC下,为了将自动释放池块内部的变量放入自动释放池,需要手动调用autorelease方法:在ARC下,只 ...
- Delphi中WebBrowser自动填表模板
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...
- (20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)
引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool ...
- Delphi中的关键字与保留字
Delphi中的关键字与保留字 分类整理 Delphi 中的“关键字”和“保留字”,方便查询 感谢原作者的收集整理! 关键字和保留字的区别在于,关键字不推荐作标示符(编译器已经内置相关函数或者留给保留 ...
- OC 内存泄露 自动释放池
花絮:看到下面的代码就想起这么一个调侃: 一个老程序员,功成名就,金盆洗手不在写代码后,决定练练书法.提笔思索良久后在纸上写下:Hello world! /********************** ...
- (五十八)NSObject实现多线程、自动释放池的补充
模拟一个图片下载的场景,图片的下载需要2s,在这期间为了保证程序的流畅,应该把图片的下载放在子线程中进行. 使用NSObject的方法performSelectorInBackground方法即可实现 ...
随机推荐
- 现代软件工程作业 github使用
Github使用 版本库的创建与同步 第一步:创建远程版本库并同步到本地 创建远程版本库 在地址栏输入www.github.com 并sign in 进入到个人主页,如下图示: 创建远程版本库:点击N ...
- ctypes 调用 dll
1. 加载 Windows API 和 C 运行库 先看例子 from ctypes import * u32 = windll.LoadLibrary('user32.dll') #加载user32 ...
- 关于es5的一些新方法
1.数组方法(1)isArray在之前我们判断数组类型的数据都是用instanceof来判断的,es5新增了对数组的判断,即Array.isArray()(2)every和some这两个方法一般用于对 ...
- 如何在centos下部署Node环境
从今年开始,养车之家的PC 和 M端 的站点 ,服务器从tomcat全部改成了Node,无论在测试环境.准生产.正式环境,我们都需要在服务器进行Node的部署,在这里我给大家详细说明下Node在lin ...
- Spring框架学习(一)
一. spring概述 Spring 框架是一个分层架构,由 7 个定义良好的模块组成.Spring 模块构建在核心容器之上,核心容器定义了创建.配置和管理 bean 的方式,如图 1 所示. 图 1 ...
- webbrower判断页面是否加载完成的好方法
public void WaitPageCompleted(int timeOutSec) { ; ; j < timeOutSec * ; j++) { _wb.Invoke(new Acti ...
- gnuWin32-mini-2016.10.30
2016-10-28 04:48 1,017,856 awk.exe ver 4.1.4 2016-10-29 00:26 77,312 bc.exe ver 1.06 2016-10-30 01:4 ...
- 如何正确的做WEB端的压力测试
1.对要测试的系统进行分析,明确需要对哪一块做压力测试.比如:淘宝网站双十一期间,秒杀跟支付,此模式用户操作中占比比较大 再比如:游戏,登录--开始战斗--结束战斗这种混合模式在用户操作中占比较大 那 ...
- BFS_Maze_求解迷宫最短路径
/* 10 10 #.######.# ......#..# .#.##.##.# .#........ ##.##.#### ....#....# .#######.# ....#..... .## ...
- iOS 之各种Crash
1.*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position ...