Delphi中對象釋放的問題

  寫前臺程序的時候經常遇到自己創建對象的情況,我們知道delphi沒有類似Java的內存回收技術,
所以要手動釋放自己創建的對象。
  大部分對象創建的時候,在create構造函數中都有一個AOwner參數,該參數用來指定對象的owner,
先看一下delphi幫助中對owner屬性的解釋:
Delphi has a built-in memory-management mechanism that allows one component to assume
responsibility for freeing another. The former component is said to own the latter. The
memory for an owned component is automatically freed when its owner's memory is freed.
The owner of a component梩he value of its Owner property梚s determined by a parameter
passed to the constructor when the component is created. By default, a form owns all
components on it and is in turn owned by the application. Thus, when the application
shuts down, the memory for all forms and the components on them is freed.

Ownership applies only to TComponent and its descendants. If you create, for example,
a TStringList or TCollection object (even if it is associated with a form), you are
responsible for freeing the object.

...

Use Owner to find the owner of a component. When one component owns another, the memory
 for the owned component is freed when its owner's memory is freed. This means that when
 a form is destroyed, all the components on the form are also destroyed.

By default, a form owns all components that are on it. In turn, the form is owned by the
application. Thus when the application shuts down and its memory is freed, the memory for
all forms (and all their owned components) is also freed.

The owner of a component is determined by the parameter passed to the constructor when
the component is created. For components created in the form designer, the form is
automatically assigned as the owner.
  這段英文的意思大概如下:當一個對象具有owner時,它的owner負責它的內存釋放。事實上TComponent
類內部有一個descendants的列表,當它自己被釋放時,它會檢查並釋放所有的descendants。也就是說,
當你爲對象指定了正確的owner屬性,它的owner會負責對象的釋放,你不必自己釋放它的。
  可以寫個很簡單的程序進行驗證:創建一個form,指定其owner爲某個button,然後free這個button,你
會看到button和form都不見了。
  當然,這個規則只對從TComponent繼承的對象適用。對於TStringList等不是從TComponent繼承的類,該
類型的對象必須手動進行釋放了。在這裏有一個誤區,就是free和nil的區別,free是釋放對象的內存,nil
是將指針變量的引用指爲空,即不引用任何東西。如果聲明的變量類型爲基本類型,比如integer,char等,
該變量在函數執行結束時會被自動釋放;而如果變量類型爲對象,則函數結束時只釋放該變量本身,而不會
釋放變量所指向的對象。對象類型的變量本身是個指針,包含對實際對象的引用。
  所以,當再碰到Create對象時,如果要指定AOwner參數,可要注意了,特別是將該參數賦爲nil時,一定
要記得自己釋放。不過,對大部分對象的創建可以指定AOwner參數爲self,最差的情況可以添爲application。
application對象在應用程序結束的時候會被釋放。
  對於TStringList這樣沒有AOwner參數的類型變量,似乎沒有捷徑可走,只能自己手動釋放了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章