2012-04-30 20:37
509人閱讀
收藏
舉報(bào)
在delphi中,有些函數(shù)或者設(shè)置會(huì)使對象自動(dòng)釋放,此時(shí)如果在次釋放會(huì)發(fā)生野指針的現(xiàn)象,導(dǎo)致莫名的錯(cuò)誤。
下面介紹幾種經(jīng)常見到的釋放規(guī)則。
(一)、使用 TObjectList
- 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;
- end;
- list.Add(btn);
- end;
- ShowMessage('TObjectList 釋放時(shí), 會(huì)同時(shí)釋放其中的對象');
- 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;
- end;
- list.Add(btn);
- end;
- ShowMessage('TList 釋放后, 其中的對象并未釋放');
- list.Free;
- end;
(二)使用 TObjectList<T>
- 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;
- end;
- list.Add(btn);
- end;
- ShowMessage('TObjectList 釋放時(shí), 會(huì)同時(shí)釋放其中的對象');
- 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;
- end;
- list.Add(btn);
- end;
- ShowMessage('TList 釋放后, 其中的對象并未釋放');
- list.Free;
- end;
(三)使用記錄而不是記錄指針
-
- function Area(rect: PRect): Integer;
- begin
- 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)));
- Dispose(P);
- end;
-
- procedure TForm1.Button2Click(Sender: TObject);
- var
- R: TRect;
- begin
- R := Rect(10, 10, 60, 50);
- ShowMessage(IntToStr(Area(@R)));
- end;
(四)使用動(dòng)態(tài)數(shù)組
- procedure TForm1.Button1Click(Sender: TObject);
- var
- arr: Array of string;
- i: Integer;
- s: string;
- begin
- for i := 0 to 3 do
- begin
- SetLength(arr, Length(arr)+1);
- arr[High(arr)] := StringOfChar(Char(i + 1), 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 23 do
- begin
- SetLength(arr, Length(arr)+1);
- arr[High(arr)] := StringOfChar(Char(i + 1), 3);
- end;
- for s in arr do ShowMessage(s);
- end;
(五)在 initialization 中建立、在 finalization 中釋放
- 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.
(六)使用記錄(現(xiàn)在的記錄支持使用方法)
- type
- TForm1 = class(TForm)
- Button1: TButton;
- procedure Button1Click(Sender: TObject);
- end;
-
-
- TBase = 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: TBase;
- begin
- X := TBase.Create('Test');
- ShowMessage(X.Name);
- X.Name := 'Test1';
- ShowMessage(X.Name);
-
- end;
-
-
-
- constructor TBase.Create(const AName: string);
- begin
- FName := AName;
- end;
-
- procedure TBase.SetName(const AName: string);
- begin
- FName := AName;
- end;
-
- end.
(七)使用接口
- type
- TForm1 = class(TForm)
- Button1: TButton;
- procedure Button1Click(Sender: TObject);
- end;
-
-
- IBase = Interface
- function GetName: string;
- procedure SetName(const AName: string);
- property Name: string read GetName write SetName;
- end;
-
-
- TBase = class(TInterfacedObject, IBase)
- 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: IBase;
- begin
- X := TBase.Create('Test');
- ShowMessage(X.Name);
- X.Name := 'Test1;
- ShowMessage(X.Name);
-
- end;
-
-
-
- constructor TBase.Create(const AName: string);
- begin
- FName := AName;
- end;
-
- function TBase.GetName: string;
- begin
- Result := FName;
- end;
-
- procedure TBase.SetName(const AName: string);
- begin
- FName := AName;
- end;
-
- end.
|