當我在一個TForm(比如MyForm)有一個程序oneProc(procedure TMyForm.oneProc)時,如果我在任何MyForm類似的程序中做TThread.Queue(nil, oneProc);,它oneProc()是如何結束的,什么時候Self被很好地初始化MyForm?
你能解釋一下為什么會這樣嗎?
procedure TMyForm.Button1Click(Sender: TObject);
begin
ProcA(ProcB);
end;
procedure TMyForm.ProcA(const Aproc: Tproc);
begin
Aproc;
end;
procedure TMyForm.ProcB;
begin
showmessage(self.className); // << this show TTMyForm (how?)
end;
uj5u.com熱心網友回復:
首先,TThread.Queue()多載以接受TThreadMethod(非匿名)和TThreadProcedure(匿名)引數。您的文本描述適用于呼叫非匿名版本的代碼。另一方面,您的代碼示例所做的事情與您描述的TThread.Queue()代碼所做的事情略有不同。但無論如何,回答你的問題——
一個非匿名的方法指標實際上包含兩個值——一個是方法的地址,一個是傳遞給方法Self引數的值(方法指標由TMethod記錄表示)。
TProc是對匿名方法的參考,非匿名方法指標可以分配給匿名方法參考。該檔案甚至是這么說的,在“使用匿名方法”一節:
方法參考也可以分配給方法以及匿名方法。例如:
type TMethRef = reference to procedure(x: Integer); TMyClass = class procedure Method(x: Integer); end; var m: TMethRef; i: TMyClass; begin // ... m := i.Method; //assigning to method reference end;但是,反之則不然:您不能將匿名方法分配給常規方法指標。方法參考是托管型別,但方法指標是非托管型別。因此,出于型別安全的原因,不支持將方法參考分配給方法指標。例如,事件是方法指標值屬性,因此您不能對事件使用匿名方法。有關此限制的更多資訊,請參閱變數系結部分。
在內部,匿名方法參考是作為編譯器生成的參考計數介面實作的,具有單個Invoke()方法。當您在代碼中撰寫匿名方法時,編譯器會生成一個Invoke()使用該代碼實作的隱藏類。匿名方法捕獲的任何變數都存盤為該類的成員。
將非匿名方法指標分配給匿名方法參考時,編譯器會生成一個類來捕獲該方法指標,然后在生成的Invoke().
因此,鑒于您顯示的代碼,編譯器會將其轉換為大致如下所示的內容(我省略了不相關的實作細節):
type
//TProc = reference to procedure;
TProc_Intf = interface
procedure Invoke;
end;
TProc_Generated = class(TInterfacedObject, TProc_Intf)
FProc: procedure of object; // type of TMyForm.ProcB()
procedure Invoke;
end;
procedure TProc_Generated.Invoke;
begin
FProc; // <-- calls FProc.Code with FProc.Data as Self!
end;
procedure TMyForm.Button1Click(Sender: TObject);
var
Intf: TProc_Intf;
begin
//ProcA(ProcB);
Intf := TProc_Generated.Create;
//TProc_Generated(Intf).FProc := @ProcB;
TMethod(TProc_Generated(Intf).FProc).Code := Addr(ProcB);
TMethod(TProc_Generated(Intf).FProc).Data := Self; // <-- Self stored here!
ProcA(Intf);
end;
procedure TMyForm.ProcA(const Aproc: {TProc}TProc_Intf);
begin
//Aproc;
Aproc.Invoke;
end;
procedure TMyForm.ProcB;
begin
ShowMessage(Self.ClassName); // <-- Self valid here!
end;
That is how the Self gets from Button1Click() to ProcB() through ProcA().
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/351736.html
標籤:德尔福
