程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 淺談引用計數

淺談引用計數

編輯:Delphi
前言 作為Delphi程序員,您可以不用看這節內容,但是如果您想更多的了解一些COM內部技術,或是在對象模型與引用模型之間可以進行很好的控制的話,筆者更希望你可以抽出些許時間來看這一切的內容,而益處提體的將很明顯,您可以自由的用一些技巧來解決讓您頭疼的問題。好了,繼續我們今天的交流; 在組件技術必備知識二中,我們對接口(Interface)進行了一些介紹,當我們並沒有深入的對接口的實現/效率/優化等問題進行進一步的禅述,而了解它們的確對於我們以後的編程是有很大的幫助的,我們都知道,每個接口都會維護一個全局變量FRefCount (這是Object Pascal裡的變量名稱,如果是在C++裡,它維護的是m_CRef),它專門用來控制接口的生命周期,或是組件的生命周期(組件/接口同樣具有生命周期),當然,我們也可以給接口強制給值Nil同樣可以釋放接口,但那是不安全的或是不應該被推薦的。在此處之所以將引用技術做為一個課題例出來就是希望各位可以對組件的優化、效率方面認識一些。而FRefCount是在_AddRef and _Release中得以實現的,如下代碼(本節所有代碼摘自Delphi6中,只要您的參考版本是Delphi4以上,代碼都是相同的)。 function TInterfacedObject._AddRef: Integer; begin   Result := InterlockedIncrement(FRefCount); end;   function TInterfacedObject._Release: Integer; begin   Result := InterlockedDecrement(FRefCount);   if Result = 0 then     Destroy; end; 從代碼中我們可以看出,接口的生命周期是在_AddRef and _Release兩個方法中控制的,事實上,這兩個方面在組件編程中,就是專門用來控制組件的生命周期(關於組件生命周期和接口生命周期我們將會近一步的進行說明。),之外它們可以說是沒有意義的,而引用計數變量(FRefCount)如果在不考慮組件的生命周期時,也是完全沒有意義的。 AddRef and Release是實現的一種名為引用計數的內存管理技術,引用計數技術是使組件自己刪除組件的最簡單的同時也是效率最高的方法。COM組件將維護一個引用計數的變量來對自己生命周期進行管理,當客戶從組件獲得一個接口時,這個引用計數變量會進行增1操作(_AddRef),當客戶釋放了對接口的調用時,組件會自動的進行引用計數的減1操作(_Release),在基於Delphi的編程中,我們可以不去考慮什麼時候進行調用這兩個方法,但是如果您一旦脫離了Delphi的話,您可能必須要考慮什麼時候調用這兩個方法,如在C++中,您就一定要自己調用這兩個方法,這也正是筆者為什麼會寫這一節的內容.簡單的來說,引用計數我們平時不需要去考慮,但是在對象引用和接口引用中,您就需要自己去調用這兩個方法,同時它還涉及到作為一個組件是去整個的釋放還是單個的釋放上以及最小單位的釋放上是有必要去考慮引用計數的。如:對於一個COM組件而言,它封裝了一些COM對象,但是用戶通過接口可能需要調用COM組件中的幾個COM對象提供的服務,那麼問題就產生了,用戶有可能在訪問完了一個COM對象再去訪問另一個COM對象或是進行互動的方式進行訪問,很不幸運的是這個組件又是一個占用內存資用很大的組件,特別提體到用戶所訪問的兩個或是更多的COM對象的同時,您如何對組件進行有效的管理呢?是用戶訪問完了一個COM對象之後就立馬釋放這個COM對象呢?還是當用戶對組件訪問完成之後再進行組件級的釋放呢?或是您更詳細的對每一個用戶已經不用的接口進行釋放呢?這都對組件的效率有些許影響。而此時我們選擇不同的方式就有可能需要自己增加引用計數變量進行控制了,如: var   oFRefCount : Integer;//對象一級的引用計數的應用 begin   ……. end;    var   cFRefCount : Integer;//組件一級的引用計數的應用。 begin   …… end; 或是直接引用FRefCount//接口一級的應用計數的應用。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved