来自万一老师的博客: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 中的自动释放策略的更多相关文章

  1. Delphi 中的自动释放策略-转

    八.使用结构体而不是结构体指针: 很重要 一.指定 Owner 后, 随 Owner 连带释放: //uses Vcl.StdCtrls, Vcl.ExtCtrls; var panel: TPane ...

  2. Delphi中关于资源释放(Free,Relealse,FreeAndNil)

    根据日常编程经验,得出一些Delphi中关于资源释放的体会. 假如有对象Obj为TObject类型: 1) Obj.Free直接释放资源后,调用OnDestroy事件,但是没有将Obj指针值置为Nil ...

  3. 简单说说Delphi中线程的释放

    线程的释放方式有两种:一种是线程在运行完成后自动释放,一种是手动释放. 无论是那种释放,都应该在线程停止后进行释放. 然而线程的停止也有两种情况:一种是不需要设置标志位,直接完成:一种是由于execu ...

  4. Objective-C中的自动释放池

    自动释放池块@autoreleasepool 自动释放池块在MRC和ARC下都可以使用.在MARC下,为了将自动释放池块内部的变量放入自动释放池,需要手动调用autorelease方法:在ARC下,只 ...

  5. Delphi中WebBrowser自动填表模板

    unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...

  6. (20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)

    引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool ...

  7. Delphi中的关键字与保留字

    Delphi中的关键字与保留字 分类整理 Delphi 中的“关键字”和“保留字”,方便查询 感谢原作者的收集整理! 关键字和保留字的区别在于,关键字不推荐作标示符(编译器已经内置相关函数或者留给保留 ...

  8. OC 内存泄露 自动释放池

    花絮:看到下面的代码就想起这么一个调侃: 一个老程序员,功成名就,金盆洗手不在写代码后,决定练练书法.提笔思索良久后在纸上写下:Hello world! /********************** ...

  9. (五十八)NSObject实现多线程、自动释放池的补充

    模拟一个图片下载的场景,图片的下载需要2s,在这期间为了保证程序的流畅,应该把图片的下载放在子线程中进行. 使用NSObject的方法performSelectorInBackground方法即可实现 ...

随机推荐

  1. 【UOJ#79】一般图最大匹配(带花树)

    [UOJ#79]一般图最大匹配(带花树) 题面 UOJ 题解 带花树模板题 关于带花树的详细内容 #include<iostream> #include<cstdio> #in ...

  2. windows2016上如何通过攻击ETERNALBLUE获得meterpreter反弹

    windows2016上如何通过攻击ETERNALBLUE获得meterpreter反弹 译:by  backlion 0x00前言 当微软发布MS17-010漏洞的补丁时,该漏洞影响的范围是从Win ...

  3. 埃及分数&&The Rotation Game&&骑士精神——IDA*

    IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...

  4. Git 自动补全

    如果你用的是 Bash shell,可以试试看 Git 提供的自动补全脚本. http://git-scm.com/download 下载 Git 的源代码,进入contrib/completion  ...

  5. 形态学及其他集合运算(Morphological and Other Set Operations)

    摘    要:本实验主要实现形态学图像处理.主要验证图像集合的交并补运算.膨胀和腐蚀处理并利用图像集合的运算,实现形态学边界抽取算法并进行特征边界抽取.同时将膨胀和腐蚀扩展至灰度图像,编写函数实现灰度 ...

  6. python 分享文件

    http://note.youdao.com/noteshare?id=1787e8bf3a71fca16005ece3e7fffb6c

  7. bzoj 2929 [Poi1999]洞穴攀行 网络流

    2929: [Poi1999]洞穴攀行 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 499  Solved: 295[Submit][Status][ ...

  8. grafana模板

    1.安静了这么久,换了一家公司,还有过年,去了上海,去了苏州,去了杭州,认识了一个人,跟老司机他们一起学k8s,所以很累很累,这是监控,也是在老司机的帮助下熟悉使用,3q!

  9. Tests for normality正态分布检验

    欢迎关注博主主页,学习python视频资源,还有大量免费python经典文章 sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/ ...

  10. C++构造函数和析构函数顺序

    构造函数    先看看构造函数的调用顺序规则,只要我们在平时编程的时候遵守这种约定,任何关于构造函数的调用问题都能解决:构造函数的调用顺序总是如下:1.基类构造函数.如果有多个基类,则构造函数的调用顺 ...