FreeAndNil這個程序是不是有些多餘? |
答題得分者是:change.jian
|
0908
一般會員 發表:10 回覆:4 積分:2 註冊:2002-12-31 發送簡訊給我 |
|
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi 0908, 請看各位大大們精闢的見解:
http://delphi.ktop.com.tw/topic.php?topic_id=48788
很慚愧,我到現在還是一知半解 ----------------------------------
小弟才疏學淺,若有謬誤尚請不吝指教
----------------------------------
------
Fishman |
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
0908,您好:
以下列的程式碼來說
procedure TForm1.Button1Click(Sender: TObject); var aObj:TComponent; begin aObj:=TComponent.Create(Self); try .... finally aObj.free; aObj:=nil; end; end;當您宣告了aObj:TComponent,程式已做了兩件事: 1.向OS要了一個可以容納TComponent物件大小的記憶體區塊 2.把aObj指向"要到的記憶體"的起始位置. 所以,即使程式沒有執行到aObj:=TComponent.Create,但以Assigned去檢查aObj的話,會發現回傳的是True值. 同理,即使執行了aObj.Free,再以Assigned函數檢查aObj,仍然會回傳True值.只有當你把aObj設為nil時,Assigned才會回傳False. 您可以把aObj想像成地址.把TComponent想像成一棟建築物.宣告 Obj:TComponent 時,其實只是告訴戶政事務所(假設戶政事務所管地址)你要在aObj這個地址建一棟建築物.至於你什麼時候建,戶政事務所並不理會.這時,如果你沒有把建築物建立起來,就開始向別人公開你的地址的話,就會發生郵差到了該地址送信時,發現沒有建築物,也沒有人收信.這時,程式就會給你一個"Access violation at address XXXXXXXX in module...."的錯誤訊息.同樣的,若干年後建築物不需要用到了,你把建築物打掉,其實只相當於呼叫物件的free方法,但戶政事務所仍然認定那個地址有建築物.直到aObj:=nil時,才是向戶政事務所通知我的房子打掉了,不存在了. 當然,如果你沒有把房子打掉,就直接跟戶政事務所說那個地址沒有用了.那麼,你的建築物將因為沒有地址,再也沒有人可以找到他的所在地了,也就是記憶體流失了.所以最省事的做法,就是建築物打掉時,也要跟戶政事務所說這個地址沒有用了,要這樣做,FreeAndNil是個不錯的方法. 故事說完了,好不好聽啊 |
jest0024
高階會員 發表:11 回覆:310 積分:224 註冊:2002-11-24 發送簡訊給我 |
//以下函數參考Delphi源碼 procedure FreeAndNil(var Obj); var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; 同於 begin Obj.Free; Obj:=nil; end; 範例一 procedure Test var Obj:TObject; begin Obj:=TObject.Create; //註Obj是指向系統建立OBJECT的一個指標 Obj.Free; Obj:=nil; {在私用程序上,程序執行完便釋放了,其他的程序未參考OBJ所 以這行可以省掉!!} end; 範例二 var Obj:TObject; procedure Test; begin Obj:=TObject.Create; //註Obj是指向系統建立OBJECT的一個指標 Obj.Free; Obj:=nil; {Obj是屬於公用的指標,可能別的程序會參考到這記憶体,如 果未指向nil,則會造成程式發生錯誤,所這行不可以省} end;學而時習之不亦樂乎! |
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
shaofu
高階會員 發表:5 回覆:136 積分:103 註冊:2003-01-07 發送簡訊給我 |
change.jian 兄講解的方式真的很好, 不過有些地方有錯, 幫忙補正一下 < class="code">
procedure foo:
var
aObj: TComponent;
begin
aObj:=TComponent.Create(Self);
end;
首先, Delphi 的物件皆是以指標實作, aObj 實際上就是一個指標,
把 aObj 當成指標來想, 後面的解說就很容易了.. aObj: TComponent;
這行說明 aObj 是個 TComponent 的物件(指標),
但這邊有一個重點 "complier 不會幫 local variable 做初使化",
也就是 aObj 的值在剛開始並沒有任何意義, 可以想為只是個亂數值...
(PS: 反之 global variable 則預設會初使化為 0) TComponent.Create(Self);
向OS要了一個可以容納TComponent物件大小的記憶體區塊,
加上物件的初使化 aObj:=TComponent.Create(Self);
把aObj指向"要到的記憶體"的起始位置.
(至此, aObj 的值才有意義) 至於之後的 address 與 value 的關係, change.jian 兄講的就很清楚了,
好比喻 發表人 -
|
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
|
OsX
版主 發表:6 回覆:151 積分:111 註冊:2003-05-03 發送簡訊給我 |
引言: Hi 插個花: Delphi有很多函數, 都是由Borland幫我們實作後方便讓我們使用, 例如一堆DateTime的相關function procedure, FreeAndNil也是同樣的道理, 若我們使用時知道他的原理便可手動去Key程式碼, 效率也許會更快, 這個函數也許是有點多餘, 但竟然Borland已經又幫我們放上去也許是有其他方面的需求. 我不是高手, 高手是正在銀幕前微笑的人.我也來插花, 之前在 Borland News Group 看到的, FreeAndNil() 這個函式由來, 並不是有其它特殊理由或原因才加進去的, 是因為有人向 Borland 反應 寫 Obj.Free; Obj := nil;看起來很笨(原文好像是Stpuid Code) 於是向 Borland 反應, Borland 便把這個函式從 Delphi6 開始加進去, 滿足 這些人的要求. |
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
|
0908
一般會員 發表:10 回覆:4 積分:2 註冊:2002-12-31 發送簡訊給我 |
|
hahalin
版主 發表:295 回覆:1698 積分:823 註冊:2002-04-14 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |