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...