線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1762
推到 Plurk!
推到 Facebook!

CREATE與PARENT屬性的關係

答題得分者是:Justmade
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-06-07 11:55:21 IP:61.66.xxx.xxx 未訂閱
請問各位!    不好意思, 再請教有關PARENT的觀念問題 我查了本站之前對self.free的一些討論後, 有幾點疑問 (由於這方面討論非常多, 僅能查到1000筆)    在Form1的 Private 上定義 myForm: TForm; myLabel: TLabel;    在 FORM1 上一支PROCEDURE有下    Procedure myProcedure; begin myForm:= TForm.Create(self); .... myLabel:= TLabel.Create(self); myLabel.Parent:= myForm; .... .... myForm.Free; end; 1.如此是否 myLabel會一併被釋放, 我測試的結果(連續執行這支procedure100次) 然後檢查記憶體並沒有損失多少(幾個byte) 反而是在 myForm.Free前先加 myLabel.Free, 在第二次執行就error 所以想確認一下, 這樣的繼承關係, 是否子項元件不需要做任何的釋放行為, 由 父項執行就可以了! 2.myForm:= TForm.Create(self); 這樣寫法, myForm是屬於TForm1的, 還是myProcedure, 因為我有測 myForm:= TForm.Create(Form1); 兩者執行下來的記憶體在釋放上是不相上下 如果用self這樣是屬於myProcedure的話, 但myForm又是宣告在Form1.private上 那procedure 自然消滅時, myForm的歸屬又是如何? 另外, 如果我procedure 這樣寫 Procedure myProcedure; var myLabel: TLabel; begin myForm:= TForm.Create(self); .... myLabel:= TLabel.Create(self); myLabel.Parent:= myForm; .... .... myForm.Free; end; 由於myLabel是定義在myProcedure, 屬local define, 所以當procedure自然消 滅時, myLabel也會一併被釋放, 是否正確? 謝謝!
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-06-07 13:59:34 IP:218.16.xxx.xxx 未訂閱
先說清楚 Parent 和 Owner 的分別,及 Self 的意思    Parent 與 Owner 的分別請參考 : 簡介 Owner 和 Parent 的分別 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=31853    而 Self 是指物件本身 在 TForm1.ProcedureA 裡 Self 就一定是指現正執行這段程式碼這個 TForm1 的 instance (可能叫 Form1 但非必然) 即使在 with XXX do 裡 Self 仍不會變了 XXX 的。 Self 更加不是指正在執行的 Procedure 了。    有關 Self 的進深應用也可參考一下 : http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30573    
引言: Procedure myProcedure; 不可能的...應是 TForm1.myProcedure 罷,分別很大的 begin myForm:= TForm.Create(self); .... myLabel:= TLabel.Create(self); myLabel.Parent:= myForm; .... .... myForm.Free; end; 1.如此是否 myLabel會一併被釋放, 我測試的結果(連續執行這支procedure100次) 然後檢查記憶體並沒有損失多少(幾個byte) 反而是在 myForm.Free前先加 myLabel.Free, 在第二次執行就error 所以想確認一下, 這樣的繼承關係, 是否子項元件不需要做任何的釋放行為, 由 父項執行就可以了!
myForm Free 掉時是會自動 Free 掉身為它的 ChildControl 的 myLabel 的沒錯。 不過在myForm.Free前先加 myLabel.Free 也沒關係丫,我測試時按很多次都沒出錯, 你試那邊出錯應是別的原因引至。 不過放在 myForm.Free 後加便會出錯了因那時 myLabel 已經 Free 了。
引言: 2.myForm:= TForm.Create(self); 這樣寫法, myForm是屬於TForm1的, 還是myProcedure, 因為我有測 myForm:= TForm.Create(Form1); 兩者執行下來的記憶體在釋放上是不相上下 如果用self這樣是屬於myProcedure的話, 但myForm又是宣告在Form1.private上 那procedure 自然消滅時, myForm的歸屬又是如何?
若執行時你個 TForm1 的 instance 叫做 Form1 的話,兩個寫法是一模一樣的 但若你在別處以另一個名字使用 TForm1 的話 (如 MyForm1 : TForm1) 那第二種寫法到執行時便會出錯了,因為那時沒有 Form1 只有 MyForm1,所以還是寫成 Self 會好點
引言: 另外, 如果我procedure 這樣寫 Procedure myProcedure; var myLabel: TLabel; begin myForm:= TForm.Create(self); .... myLabel:= TLabel.Create(self); myLabel.Parent:= myForm; .... .... myForm.Free; end; 由於myLabel是定義在myProcedure, 屬local define, 所以當procedure自然消 滅時, myLabel也會一併被釋放, 是否正確?
這要分兩個層面來說 1. myLabel 指向的 TLabel 實體, 是在 myForm.Free 時已釋放了(如上所說) 2. myLabel 這個本地變數,在這個 Procedure 完成後會被自動釋放 其實若非別個 procedure 要用到它們,否則不單是 MyLabel, MyForm 也可放在 Local variable 因為你在一個 procedure 內建立及完成操作,可不必要在 Form1 裡加兩個平時用不到的變數。 最後, TLabel 的建成部份建議儘量改成 : myLabel:= TLabel.Create(myForm); 因為 myForm 作為這個 Lable 的 Owner 比用 Self(Form1) 作為 TLabel 的 Owner 更合理。
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-06-08 00:23:41 IP:61.66.xxx.xxx 未訂閱
感謝 justmade 兄的精闢說明, 讓我對這方面有更進一步的認識 另外再請教一個問題    
TForm1.procedure Myprocedure;
  var myForm: TForm;
      myLabel: TLabel;
begin
  myForm:= TForm.Create(self);
  myForm.name:= 'Test1';       myLabel:= TLabel.Create(myForm);
   ...
   ...
end;
這裡有點困惑, myForm被create, 如果不加紅色部份, 可以被重覆執行 但如果加上紅色的form.name , 則在執行第二次即錯誤 "a Component named test1 already exists", 按上述說, 宣告 local variable, 在 procedure 結束時應自然釋放掉, 但測試結果, 如果不加 free 其實還是存在於記憶體中, 那這要如何解釋, 我的想法是 TComponent 的物件雖定義在procedure中, 但其父項仍是屬於Form物件, 所以即使procedure結束也不會影響所create的特性, 一樣得手動free才可以, 如果是定義 var myVar: integer的話, 則procedure結束, myVar自然釋放, 不知對不對? 發表人 - P.D. 於 2003/06/08 00:28:30
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-06-08 12:46:04 IP:218.16.xxx.xxx 未訂閱
引言:
TForm1.procedure Myprocedure;
  var myForm: TForm;
      myLabel: TLabel;
begin
  myForm:= TForm.Create(self);
  myForm.name:= 'Test1';
  myLabel:= TLabel.Create(myForm);
   ...
   ...
end;
這裡有點困惑, myForm被create, 如果不加紅色部份, 可以被重覆執行 但如果加上紅色的form.name , 則在執行第二次即錯誤 "a Component named test1 already exists", 按上述說, 宣告 local variable, 在 procedure 結束時應自然釋放掉, 但測試結果, 如果不加 free 其實還是存在於記憶體中, 那這要如何解釋, 我的想法是 TComponent 的物件雖定義在procedure中, 但其父項仍是屬於Form物件, 所以即使procedure結束也不會影響所create的特性, 一樣得手動free才可以, 如果是定義 var myVar: integer的話, 則procedure結束, myVar自然釋放, 不知對不對?
引言: 這要分兩個層面來說 1. myLabel 指向的 TLabel 實體, 是在 myForm.Free 時已釋放了(如上所說) 2. myLabel 這個本地變數,在這個 Procedure 完成後會被自動釋放
myForm:= TForm.Create(self); 這其實做了兩個動作 1. 建立了一個 TForm Class 的物件 2. 將這物件的指標指給 myForm 這個本地變數 所以 myForm 只給我們去存取 那個 TForm Class 物件的一個途徑 看以下程式碼
TForm1.procedure Myprocedure;
  var myForm,myForm2: TForm;
      myLabel: TLabel;
begin
  myForm:= TForm.Create(self);
  myForm2 := myForm;
  myForm := self;
   ...
end;
到最後 myForm 是指向 Form1 而不是新建立的 TForm Instance。 所以 myForm 本身並不是那個新建立的 TForm Instance,而只是一個 Pointer 形態的變數罷了。 當 Procedure 完結時,自動釋放的是 myForm 這個本地變數 myForm 所指向物件並沒有改變,只是少了一個指向他的變數罷了。 舉一個現實中的例子 : 小弟在 K.Top 的戶口叫 Justmade. 大家可以通個 Justmade 來聯絡我(如寄短訊), 若有天小弟給 K.Top 刪除了戶口, 是沒有 Justmade 這個戶口了,但我依然存在的。 若你不用 myForm.Free 來釋放那個 Instance 而讓procedure 結束,這是這個樣子。
系統時間:2024-05-05 18:54:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!