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 := 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;
时间: 2024-10-09 23:56:53

Delphi 中的自动释放策略-转的相关文章

Delphi 中的自动释放策略

http://www.cnblogs.com/del/archive/2011/12/21/2295794.html Delphi 中的自动释放策略 一.指定 Owner 后, 随 Owner 连带释放: //uses Vcl.StdCtrls, Vcl.ExtCtrls; var   panel: TPanel; procedure TForm1.Button1Click(Sender: TObject); begin   panel := TPanel.Create(Self);   pan

简单说说Delphi中线程的释放

线程的释放方式有两种:一种是线程在运行完成后自动释放,一种是手动释放. 无论是那种释放,都应该在线程停止后进行释放. 然而线程的停止也有两种情况:一种是不需要设置标志位,直接完成:一种是由于execute方法中做了循环,需要设置标志位才能停止. 如果线程已经停止并且自动释放,再去手动停止,就会报错. 下面看代码: 1.自动停止后自动释放的线程: [delphi] view plain copy constructor TTestThread.Create; begin inherited Cre

Delphi中线程的释放介绍[转]

线程的释放方式有两种:一种是线程在运行完成后自动释放,一种是手动释放. 无论是那种释放,都应该在线程停止后进行释放. 然而线程的停止也有两种情况:一种是不需要设置标志位,直接完成:一种是由于execute方法中做了循环,需要设置标志位才能停止. 如果线程已经停止并且自动释放,再去手动停止,就会报错. 下面看代码: 1.自动停止后自动释放的线程: constructor TTestThread.Create;begin inherited Create( True ); FreeOnTermina

ios中的自动释放池

自动释放池中是否有虑重功能 1 @autoreleasepool { 2 UIView *view = [UIView alloc] init] autorelease]; 3 [view autorelease]; 4 } 这样写在自动释放池的队列中是两个对象还是一个对象,就是说把view加到自动释放池的队列时,队列本身是否对内容进行了虑重 防止对象的重复添加,比较view里面在队列中了,再次调用autorelease时还有没有作用. 于是写了一个测试代码 1 - (BOOL)applicat

Delphi中WebBrowser自动填表模板

unit Unit1;interfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls,MSHTML, SHDOCVW,IdGlobal;type  TMainFrm = class(TForm)    btnTest: TButton;    edURL: TEdit;    Label1: TLabel;    procedure btnTe

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

引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool中.所以我们也在Cocos2d-x中克隆了一套CCAutoreleasePool.两者的用法基本上一样,所以假如你没有涉及过ios开发,你可以看看苹果官方文档NSAutoreleasePool Class Reference. CCAutoreleasePool Cocos2d-x的CCAutore

Delphi中的关键字与保留字

Delphi中的关键字与保留字 分类整理 Delphi 中的“关键字”和“保留字”,方便查询 感谢原作者的收集整理! 关键字和保留字的区别在于,关键字不推荐作标示符(编译器已经内置相关函数或者留给保留实现),二保留字是根本不可能作标示符(编译时有警示!) [系统保留字] and            array          as             asm begin          case           class          const constructor   

29-oc自动释放池

autorelease基本概念 什么是自动释放池? autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 自动释放池的优点是什么 不用再关心对象释放的时间 不用再关心什么时候调用release 简述自动释放池的原理 autorelease实际上只是把对release的调用延迟了,对于每一个autorelease,系统只是把该 Object放入了当前的

OC基础(十三)autorelease自动释放池

autorelease 自动释放池 autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 优点:不用再关心对象释放的时间,不用再关心什么时候调用release 原理:autorelease实际上只是把对release的调用延迟了,对于每一个autorelease,系统只是把该 Object放入了当前的autorelease pool中,当该pool被