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; 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))); //2000
Dispose(P);
end;
{}
procedure TForm1.Button2Click(Sender: TObject);
var
R: TRect;
begin
R := Rect(, , , );
ShowMessage(IntToStr(Area(@R))); //2000
end;
Delphi 中的自动释放策略的更多相关文章
- Delphi 中的自动释放策略-转
八.使用结构体而不是结构体指针: 很重要 一.指定 Owner 后, 随 Owner 连带释放: //uses Vcl.StdCtrls, Vcl.ExtCtrls; var panel: TPane ...
- 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方法即可实现 ...
随机推荐
- 【BZOJ2876】【NOI2012】骑行川藏(数学,二分答案)
[BZOJ2876][NOI2012]骑行川藏(数学,二分答案) 题面 BZOJ 题解 我们有一个很有趣的思路. 首先我们给每条边随意的赋一个初值. 当然了,这个初值不会比这条边的风速小. 那么,我们 ...
- unity3D 涂涂乐使用shader实现上色效果
unity3D 涂涂乐使用shader实现上色效果 之前我博文里面发过一个简单的通过截图方式来实现的模型上色方法,但是那个方法不合适商用,因为你需要对的很准确才可以把贴图完美截取下来,只要你手抖了一下 ...
- 跨域通信的解决方案JSONP
在web2.0时代,熟练的使用ajax是每个前端攻城师必备的技能.然而由于受到浏览器的限制,ajax不允许跨域通信. JSONP就是就是目前主流的实现跨域通信的解决方案. 虽然在在jquery中,我们 ...
- DevExpress Components16.2.6 Source Code 重编译教程
DevExpress 是一个比较有名的界面控件套件,提供了一系列优秀的界面控件.这篇文章将展示如何在拥有源代码的情况下,对 DevExpress 的程序集进行重新编译. 特别提示:重编译后,已安装好的 ...
- Centos 7.3 下 的QT 输入中文
我的QT 目录在 /opt/Qt/Tools/QtCreator,进入到 /bin 目录,然后运行 ./qtcreator.sh 就可以运行 在qtcreator.sh 中加入 export QT_ ...
- 洛谷P2345 奶牛集会
题目背景 MooFest, 2004 Open 题目描述 约翰的N 头奶牛每年都会参加“哞哞大会”.哞哞大会是奶牛界的盛事.集会上的活动很 多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚 ...
- libevent学习笔记(参考libevent深度剖析)
最近自学libevent事件驱动库,参考的资料为libevent2.2版本以及张亮提供的<Libevent源码深度剖析>, 参考资料: http://blog.csdn.net/spark ...
- python基础5--模块
模块 一.模块简介 模块是一个包含有定义的函数和变量的文件,其后缀名是.py.Python的强大之处在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相应的Python库支持. 标准 ...
- SpringCloud学习(2)——Rest微服务案例
创建父工程: microservicecloud 创建公共模块api:microservicecloudapi SQL脚本: 此学习路线总共创建3个库, 分别为clouddb01, clouddb0 ...
- HTML不常用的表单属性-fieldset
这是代码 这是生成的样子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...