zoukankan      html  css  js  c++  java
  • 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);
      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
    delphi lazarus opengl 网页操作自动化, 图像分析破解,游戏开发
  • 相关阅读:
    React教程(一) React介绍与搭建
    微信公众号订阅号以及服务号通过网页授权获取用户openid方法
    AES,DES加密JS源文件及其使用方法
    R 分类进行数值处理
    C++ const 关键字总结
    软工lintcode作业
    [恶意软件分析]DroidBox的环境搭建与使用
    Android第三次作业
    Android第二次作业
    android 第一次作业
  • 原文地址:https://www.cnblogs.com/delphi-xe5/p/5399863.html
Copyright © 2011-2022 走看看