Subject:
匿名过程转换成事件过程的意义和方法
[Print This Page]
Author:
zzzl
Time:
2011-1-5 00:14
Subject:
匿名过程转换成事件过程的意义和方法
先贴一小段例子说明这个方法的意义
procedure
TForm1.
Button1Click
(
Sender
:
TObject
);
var
s
:
string
;
begin
s
:=
'aa'
;
//用这句表示s的值经过一个复杂的计算,得出值为aa
timer1
.
OnTimer
:=
NotifyEvent
(
//给这个TTimer控件指定onTimer事件
procedure
(
sender
:
TObject
)
begin
memo1
.
Lines
.
Add
(s
+
sender
.
ToString
);
//这里使用了s变量,是的,它能“看见”s
end
);
end
;
如果用别的方法实现上面的功能,s可能会被放在TForm1宝贵的private区域,以让OnTimer事件函数能看到它。而这个方法使你可以连贯的表达你的意图:计算s的值,以某种方式显示它。你不必把这个整体的逻辑划分到两个函数里。
有很多个理由需要把一个匿名过程转换成事件类型,但delphi似乎没有直接提供这个方法,如果有谁知道的话记得告诉我。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
我自己的实现方法很简单,也很笨,代码很短,贴出来了
_CPack
=
class
(
TComponent
)
//这个类不应被客户端看到,它只为NotifyEvent函数使用,所以我在前面加了个下划线。
private
fProc
:
TProc
<
TObject
>;
procedure
event
(
sender
:
TObject
);
end
;
procedure
_CPack
.
event
(
sender
:
TObject
);
begin
fProc
(
sender
);
end
;
function
NotifyEvent
(p
:
TProc
<
TObject
>
)
:
TNotifyEvent
;
var
obj
:
_CPack
;
begin
obj
:=
_CPack
.
Create
(
Application
);
obj
.
fProc
:=
p;
Result
:=
obj
.
event
;
end
;
这个实现方法的缺点是每调用一次
NotifyEvent都要产生一个
TComponent
对象,不过
NotifyEvent的调用次数应该是在编译时确定的,所以数量微不足道,如果要在运行时确定,你可以将NotifyEvent的返回值暂存起来用。
这个缺点对我来说不成问题,因为我在写客户端程序时倾向于不释放资源以换取稳定性。
如果你实在在意这个leak,可以给NotifyEvent加一个out id参数,有了id,你就可以控制生存期了。
另一个实现在这里(
http://kindi.tistory.com/entry/Using-anonymous-methods-in-method-pointers
)
,韩语的,不知在说什么,但我把它的代码拷出来,上面的示例可以编译通过,也没有我上面方法的问题,但唯一的问题是,它输出的结果是“Timer1”,而不是“aaTimer1",换句话说,s的值不见了。
Author:
friendlinzh
Time:
2011-8-18 10:26
procedure event(sender: TObject);
Welcome to CnPack Forum (http://bbs.cnpack.org/)
Powered by Discuz! 5.0.0