為什么在訪問對象之前我不應該使用“if Assigned()”?這個問題是stackoverflow上人們特別評論的延續,我現在已經看過幾次不同的時間了。我和教我Delphi的開發人員一樣,為了保證安全,if assigned()在釋放對象之前,以及在做其他各種事情之前總是先做檢查。但是,我現在被告知我不應該添加此支票。我想知道如果我這樣做,應用程序編譯/運行的方式是否存在任何差異,或者它是否會對結果產生影響...if assigned(SomeObject) then SomeObject.Free;假設我有一個表單,我在表單創建時在后臺創建一個位圖對象,并在完成表單時釋放它?,F在我想我的問題是,當我試圖訪問可能在某些時候可能已經免費的對象時,我已經習慣了對我的很多代碼進行檢查。即使沒有必要,我也一直在使用它。我喜歡徹底......unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FBitmap: TBitmap;
public function LoadBitmap(const Filename: String): Bool;
property Bitmap: TBitmap read FBitmap;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);begin
FBitmap:= TBitmap.Create;
LoadBitmap('C:\Some Sample Bitmap.bmp');end;procedure TForm1.FormDestroy(Sender: TObject);begin
if assigned(FBitmap) then begin //<-----
//Do some routine to close file
FBitmap.Free;
end;end;function TForm1.LoadBitmap(const Filename: String): Bool;var
EM: String;
function CheckFile: Bool;
begin
Result:= False;
//Check validity of file, return True if valid bitmap, etc.
end;begin
Result:= False;
EM:= '';
if assigned(FBitmap) then begin //<-----
if FileExists(Filename) then begin
if CheckFile then begin
try
FBitmap.LoadFromFile(Filename);
except現在讓我們說我正在引入一個名為TMyList的新自定義列表對象TMyListItem。對于此列表中的每個項目,我當然必須創建/釋放每個項目對象。創建項目有幾種不同的方法,以及一些銷毀項目的不同方法(添加/刪除是最常見的)。我確信將這種保護放在這里是一種非常好的做法......在許多情況下,至少我希望在我嘗試釋放它之前仍然創建對象。但是你永遠不知道未來在對象被釋放之前會發生什么樣的滑動。我總是使用這張支票,但現在我被告知我不應該這樣,而且我仍然不明白為什么。
3 回答

Helenr
TA貢獻1780條經驗 獲得超4個贊
Free
有一些特殊的邏輯:它檢查是否Self
是nil
,如果是這樣,它返回而不做任何事情-這樣你就可以安全地調用X.Free
,即使X
是nil
。當你編寫析構函數時,這很重要 - 大衛在他的答案中有更多的細節。
您可以查看源代碼Free
以了解其工作原理。我沒有方便的Delphi源代碼,但它是這樣的:
procedure TObject.Free;begin if Self <> nil then Destroy;end;
或者,如果您愿意,可以將其視為等效代碼,使用Assigned
:
procedure TObject.Free;begin if Assigned(Self) then Destroy;end;
您可以編寫自己的方法來檢查if Self <> nil
,只要它們是靜態(即,不是virtual
或dynamic
)實例方法(感謝David Heffernan的文檔鏈接)。但是在Delphi庫中,Free
我所知道的唯一方法是使用這個技巧。
因此,Assigned
在調用之前,您無需檢查變量是否存在Free
; 它已經為你做到了。這就是為什么建議是調用Free
而不是Destroy
直接調用的原因:如果你在nil
引用上調用了Destroy ,你就會遇到訪問沖突。
添加回答
舉報
0/150
提交
取消