預裝入對象

預裝入對象


張健姿
01-6-22 下午 03:17:13


在PowerBuilder 5.0中支持全編譯代碼,但用於採用這種方法存在編譯時間長、編譯後可執行文件量大等缺點,所以在不少場合,我們仍採用僞編譯方式,就是將裝載對象和源代碼的PBL文件編譯成PowerBuilder的動態鏈接庫(.PBD)。PowerBuilder的動態鏈接庫中裝載的是與源程序庫中源代碼相匹配的二進制表示。在運行時,對象(包括函數)依照"需要時調用"的原則,從.PBD中裝入內存,這就使可執行程序的字節數大大縮小,執行效率會提高,而且由於只有那些要用到的對象才被即時裝入內存,使系統需要進行內存交換的機會就少得多,因而應用的運行也就更快。
但有時我們也會發現用戶在進行打開窗口等操作時系統的響應速度較慢,特別是在客戶機的配置較低的情況下,這種情形尤爲突出。我們知道,當程序調用一個新的對象時,系統要到各個.PBD文件中查找這個對象,如果這個對象是由其它對象繼承而來,那麼其所有的祖先對象都需要裝入內存。如應用軟件十分龐大,這種查找和裝入顯然是十分消耗時間的。
這裏我們介紹一種預裝入對象的辦法,可以在一定程度上解決這個問題。預裝入對象就是改變對象初始裝入的時間,也就是說在用戶對應用並沒有反應速度的要求時裝入了對象,而不是在用戶需要該對象時才裝入(如打開一個窗口時)。預裝入對象可以明顯地提高性能,這種技術給用戶的印象是在用戶真正要求系統的響應速度時所有對象的裝入都加快了。最適合做這些預裝入的地方是在APPLICATION的OPEN事件中。在PowerBuilder 5.0開發工具中並沒有直接提供這樣的功能,但我們可以用一些簡單的技巧來實現它,這就是使用一個非可視化對象。
我們首先應當知道:一些對象,如非可視化對象等,被調用時全部裝入內存,而另一些對象,如函數,只裝入需要的部分。因此使用一個非可視化對象可能比使用一個全局函數更快,當然還與它的大小和功能有關。
您不必在應用的OPEN事件中預裝入所有的對象,而是預裝入那些最經常被用作爲祖先的對象。具體的做法是將這個非可視化對象定義成一個變量。這個非可視化對象一直保留在內存中直到應用結束,這可使應用更加緊湊。這樣做的另一個好處是,一旦您定義了一個對象的指針作爲全局變量,就可以在軟件 的任何地方利用這個指針,引用這個對象的常量、函數和其它的特性。
具體的步驟可以這樣進行:
步驟一:創建一個預裝入的對象
創建一個Non_Visual_Object類型的用戶對象,將該對象以您選定的名字存盤。在本例中採用NVO_Object_Pre_Loader.
在該對象中,建立一個Powerobject的對象數組叫做IPO_Pre_Loaded_objects[]。Powerobject對象是Pow-erBuilder對象層次中最高層次的對象(見前文《PowerBuilder面向對象的程序設計》),因此它能被分配給任何一個PowerBuilder標準的或自定義對象。另外建立一個整型的變量做爲數組的索引,我們叫它爲ii_Idx,並且將它初始化爲0。這兩個變量均爲實例變量。
PRIVATE:/*限制對這兩個變量的訪問權限*/
/*我們假設預裝入的對象數最多不超過10,當然開發者也可根據實際情況調整*/
PowerObject IPO_Pre_Loaded_objects[10]
Integer ii_Idx=0
注意,我們應當在這裏就預先定義數組的大小,這樣可以使這個對象預先保留內存而且在自身預裝入時也能運行得更快。
步驟二:創建預裝入函數
現在創建一個用戶對象函數叫做NVOF_Pre_Load_Object。這個函數有一個參數:APO_Object,它也是Powerobject類型。函數的代碼如下。
/*
函數:NVOF_Pre_Load_Object
功能:To pre_load often used ancestor objects
參數:Power Object APO_Object
返回值:integer
1:成功,-1: 失敗
*/
ii_Idx++
/*將要預裝入的對象賦值給這個數組*/
IPO_Pre_Loaded_Objects[ii_Idx]=APO_Object
/*檢驗賦值是否成功*/
If isvalid(IPO_Pre_Loaded_objects[ii_Idx])then
Return 1
else
Return -1
end if
步驟三:創建可以放入調用用戶對象代碼的用戶事件
在這個對象上爲開發者建立一個可放入對預裝入對象調用的代碼。我們定義了使用一個"聲明"的事件,該事件將在對象的CONSTRUCTOR事件中被觸發。我們可以將這個用戶事件命名爲NVO_UE_DECLARATIONS,並且將下面的代碼放入對象的CONSTRUCTOR事件中。
This.Post Event("nvo_ue_declarations")
在NVO_UE_DECLARATION事件中您可以放入對預裝入對象的調用。
步驟四:預裝入對象
這段代碼存在NVO_UE_DECLARATION事件中。可能您的應用需要更多或更少的預裝入對象,我們只假設有這樣幾個常用的祖先對象類w_WindowBase、udw_DataWindow、uo_UserObjectBase和m_MenuBase。這些對象分別代表我們的窗口類、用戶對象數據窗口類、用戶對象類和菜單類的祖先對象。
NVO_UE_DECLARATON事件中的代碼如下:
/*聲明指向這些對象的局部變量*/
Window lWindow
UserObject lUO
DataWindow lDW
Menu lMenu
/*對每一個需要預裝入的對象,使用Create語句創建一個該對象的實例,並調用預裝入函數將這個實例保存在內存中*/
/*創建一個窗口基類的實例*/
lWindow=Create w_WindowsBase
NVOF_Pre_Load_Object(lWindow)
/*創建一個DataW-indow的用戶對象基類的實例*/
lDW=Create udw_DataWindowBase
NVOF_Pre_Load_object(lDW)
/*創建一個用戶對象的基類實例*/
lUO=uo_UserObjectBase
NVOF_Pre_Load_Object(lUO)
/*創建一個菜單實例*/
lMenu=Create m_MenuBase
NVOF_Pre_Load_Object(lMenu)
一般來講,動態調用的對象,都是那些用字符串變量調用的對象,將不包含在.EXE文件中。例如,如果您用Open(mywin,"My_Window")打開了一個窗口,My_Window窗口並不自動地包含在您的EXE文件中。如果編譯成.PBD文件,則會包含在.PBD當中。但是如果您用這種方法預裝入這個對象,該窗口在.PBD和.EXE編譯技術下都將被包含。
步驟五:初始化預裝入對象
爲了使對象進入內存,還剩下最後的一步。我們必須將預裝入對象本身裝入內存。您可以選擇在應用頻繁使用部分開始工作前的任何地方做這件事。一般常用的是在APPLICA-TION的OPEN事件中。需要的代碼如下:
anvo_object_pre_loader=Create NVO_Object_Pre_loader.
這段程序將建立這個非可視化對象,該可視化對象就會激發對象的聲明事件,從而預裝入各個對象。
最後一點需提請注意的是,不要忘記在您的APPLI-CATION的CLOSE事件中加上DESTROY anvo_object_pre_loader這樣一條語句,否則這個應用將造成所謂的內存漏洞(Memory Leak)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章