• 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 := 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;
  • 相关阅读:
    BZOJ_3589_动态树_容斥原理+树链剖分
    吴裕雄--天生自然ORACLE数据库学习笔记:SQL语言基础
    吴裕雄--天生自然ORACLE数据库学习笔记:常用SQL*Plus命令
    吴裕雄--天生自然python数据清洗与数据可视化:MYSQL、MongoDB数据库连接与查询、爬取天猫连衣裙数据保存到MongoDB
    吴裕雄--天生自然PYTHON爬虫:使用Selenium爬取大型电商网站数据
    吴裕雄--天生自然PYTHON爬虫:使用Scrapy抓取股票行情
    吴裕雄--天生自然PYTHON爬虫:爬取某一大型电商网站的商品数据(效率优化以及代码容错处理)
    吴裕雄--天生自然PYTHON爬虫:爬取某一大型电商网站的商品数据(优化)
    吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:从零开始实现识别手写数字的神经网络
    吴裕雄--天生自然神经网络与深度学习实战Python+Keras+TensorFlow:神经网络的理论基础
  • 原文地址:https://www.cnblogs.com/del88/p/6358851.html
Copyright © 2020-2023  润新知