delphi類訊息的處理機制

2021-04-13 13:30:10 字數 2300 閱讀 8586

delphi

類訊息的處理機制

文章不涉及

windows

訊息迴圈和更複雜的技術,只從

delphi

類繼承及類自身的訊息處理分析

,是自己的學習心得和體驗

. 1.

搜尋類本身有沒有處理該訊息值的函式

,如果有

,則終止迴圈

.迴圈次數

:1 2.

搜尋父類有沒有處理該訊息值的函式

,如果有

,則終止迴圈

.迴圈次數

2 3.

,直到object

4.搜尋類本身在沒有預設處理函式

,如果有

,則終止迴圈

5.搜尋父類有沒有預設處理函式6..

直到object.(

預設處理函式

,object

一定有)

其實,4,5,6

步驟在**實現時

,只查詢了一次

,這要歸功於

vmt(

虛函式表

),其簡化後的

vmt表如下(此圖

僅說明原理,並不表示編譯器一定也是如此實現

一般而言

,虛函式

dispatch

是不會過載的,在

delphi

源**中

,它的實現體是組合語言

,過載這個函式沒有什麼實際意義了

.)當然

,有特殊需要或高手表演時就可以過載的

.而虛函式

defaulthandler

是容易過載的,在

tobject類中,

該方法是乙個空操作

,在其繼承類中

,可以過載.

轉到原題

:如果某一類如

tmyclass類,

它與tobject

之間可以有任意多個父子類,當用

tmyclass.dispatch

呼叫時,

實際是呼叫的

tobject.dispatch

函式,dispatch

首先呼叫另一函式

getdynamethod,

它查詢動態方法表

(dmt)

中是否有訊息值等於傳遞訊息結構中第乙個成員的值

,如果有

,就呼叫相應的方法

,如果沒有

,則父類的動態方法表繼續查詢

.直到找到相應處理過程或

tobject

的動態方法表為

nil時注:

我認為,

在delphi

中的訊息過程

,本身就是乙個動態方法

.其記憶體位址寫入動態方法表中

,如果不是這樣

,怎麼會從

dmt中查詢呢

,這只是個人推測.

當然,如果用getdynalmethod

方法查詢不到相應的處理方法時

,dispatch

則會呼叫

defaulthandler函式,

這時用的是虛函式表

vbt,

一次操作就能馬上找到了.

這個訊息過程

,本身也體現了

,vmt

和dmt

的差別了

.vmt

執行函式快捷,省時

,單佔記憶體.而

dmt執行函式需要遞迴查詢

,效率低些.

下面是引用

nicrosoft

申旻的內容

:比較一下vmt

dmt

的區別:

vmt

中的虛函式非常齊全,因此對每個虛函式的入口位址只需要簡單的

[vptr + n]

的運算即可得到,但是

vmt

容易消耗記憶體(有冗餘)。而

dmt

比較節省空間,但要定位到沒有被覆蓋的函式的入口位址時,將非常耗費時間。

一般情況下,幾乎每個子類都要覆蓋的函式/方法,就將它宣告為

virtual

;如果類層次很深,或子類很多,但某個函式/方法只被很少的子類覆蓋,就將它宣告為

dynamic

。當然,具體就需要自己把握來選擇了。

Delphi異常處理機制

delphi的異常處理方式有兩種 try.except.end try.finally.end try.except主要用於捕獲異常,只有出現異常的時候才會執行except部分。try.finally主要用於資源釋放,無論try語句塊是否有異常都會執行finally語句塊。如下面的 1 try2 r...

handler訊息處理機制

handler主要用來更新ui 因為涉及到執行緒安全,android必須在ui執行緒 即主線程 裡才能更新ui,在其他執行緒裡更新ui會報錯,而一些耗時的操作又必須通過開啟新的執行緒來執行,這就要用到handler來傳遞訊息了。在主線程中建立乙個handler的例項,並重寫handlermessag...

非同步訊息處理機制

借鑑 為什麼不能在子執行緒更新ui?1 ui是非執行緒安全的,主線程和子執行緒同時更新ui的話會導致錯誤,如ui錯亂之類的。2 ui更新是很耗效能的,更別說為了執行緒安全加鎖了,最簡單的方法就是更新ui的操作放到乙個執行緒中,即主線程 handler機制 looper 維持乙個thread物件以及m...