介绍两个在DELPHI下支持接口的类
来源:互联网 发布:ubuntu 修改帐号密码 编辑:程序博客网 时间:2024/05/16 17:19
DELPHI虽然很好,但目前不流行,所以相关的资料相对比较少,以前我也是花了不少时间才有所得。
为了方便同行,有时间我会把一些经验在这里和大家分享。
用过的都知道,在DELPHI WIN32下使用接口会有点复杂。一般通过继承TInterfacedObject来实现接口,而TInterfacedObject子类实例是由DELPHI根据引用计数来自动管理释放的。稍不注意,很容易出现异常。
所以使用DELPHI的接口要注意以下事项:
1.当使用接口变量时,如:p:Interface,要注意p的生命期。
在方法内部定义的p,方法执行结束时,p的生命期才算结束。
定义全局的p,只有在应用退出时,p的生命期才算结束。
在类内定义p作为属性,只有该类实例释放时,p才算用完。
所以如果p引用的对象在p的生命期结束前就释放了,很容易出现一些莫名其妙的异常。
当然,你在用完p后能 p:=nil,是一个好的习惯。
2.对于表达式: (对象 as 接口).方法(..) ,可以认为DELPHI会产生一个局部的接口变量,所以如果对象在这局部范围退出前会被释放的话,退出局部范围时会触发异常。解决的办法是:p := 对象 as 接口,显式使用接口变量,用完就设为NIL。
3.尽量把接口作为参数。譬如:定义一过程 procedure aaa(const p:Interface) ;,如果使用时是:aaa(TTestClass.Create(..)),那么肯定会导致内存泄漏。
4.TInterfacedObject及其子类的实例,在创建后若未赋值给任何接口变量,需要手动释放。
这里介绍两个类,或许对你有用。
1.TCommonInterfaced。继承它可以实现接口,特点是屏蔽DELPHI的自动管理,由开发人员来手动管理实例的释放。
2.TEventInterfaced。继承它可以实现接口,特点是在激活实例的自动释放功能后,实例会在外部用完时由DELPHI来释放;若没有激活自动释放功能,则手动释放。这个类主要用在事件模型下,类似于JAVA的事件模型,监听器是以接口形式挂在事件源上的,只有当事件源撤销后,监听器才能释放。所以,如果监听器是继承自 TEventInterfaced,那么事件源在撤销前激活监听器的自动释放功能,那么DELPHI就能选择适当的时机释放监听器了。
源代码如下:
********************************************************************
unit euBase;
interface
uses Classes,SysUtils ;
Type
//普通的接口对象。当接口不再使用时不会自动释放对象。
TCommonInterfaced = class(TInterfacedObject)
protected
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
//专用在事件模型的接口对象。
//所以当需要释放实现接口的对象时,只要激活接口的自动释放功能,对象就会在不使用接口时自动释放
IEventInterface = interface(IInterface)
['{4A8C144E-07B9-4357-8BF0-EE57D2F69888}']
procedure ReleaseInIdle;
end;
{
专用在事件模型的接口对象。
当需要释放实现接口的对象时,只要激活接口的自动释放功能,
对象就会在不使用接口时自动释放。
}
TEventInterfaced = class(TInterfacedObject, IEventInterface)
private
mAutoRelease: Boolean;
procedure ReleaseInIdle;
protected
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
implementation
{ TCommonInterface }
{
****************************** TCommonInterfaced *******************************
}
procedure TCommonInterfaced.AfterConstruction;
begin
end;
procedure TCommonInterfaced.BeforeDestruction;
begin
end;
function TCommonInterfaced._AddRef: Integer;
begin
Result:=1 ;
end;
function TCommonInterfaced._Release: Integer;
begin
Result:=1 ;
end;
{ TEventInterface }
{
******************************* TEventInterfaced *******************************
}
procedure TEventInterfaced.AfterConstruction;
begin
inherited;
mAutoRelease:=false ;
end;
procedure TEventInterfaced.BeforeDestruction;
begin
inherited;
end;
procedure TEventInterfaced.ReleaseInIdle;
begin
mAutoRelease:=true ;
end;
function TEventInterfaced._AddRef: Integer;
begin
if (RefCount=0) and (mAutoRelease=false) then Inherited _AddRef() ;
Result:=Inherited _AddRef() ;
end;
function TEventInterfaced._Release: Integer;
begin
if (RefCount=2) and (mAutoRelease=true) then
begin
Inherited _Release() ;
Result:=Inherited _Release() ;
end
else if (RefCount<>1) or (mAutoRelease=true) then
Result:=Inherited _Release()
else
Result:=Inherited _Release() ;
end;
end.
*******************************************************************
USE的单元可能需要补充,因为源代码是摘录的。
- 介绍两个在DELPHI下支持接口的类
- Delphi下的接口编程
- Delphi下的接口编程
- Delphi下的接口编程
- 使Android支持html 的两个接口
- Delphi 接口:两个接口有相同名称的方法
- Delphi的接口编程基础介绍
- 图形化的PageControl皮肤(在delphi和Lazarus环境下都支持)
- delphi下的接口编程学习笔记
- Delphi类在实现接口时,可以任意的升降接口方法的可见度。
- Delphi接口使用实例介绍
- delphi下支持64位的钩子实现
- Delphi 对XML的支持---TXMLDocument类
- Delphi中支持Unicode的TStrings类
- Delphi 对XML的支持---TXMLDocument类
- Delphi的Unicode支持
- 在delphi下TClientSocket的使用技巧
- 我的delphi下的接口编程学习笔记
- 用Class组合实现Div+CSS布局
- 非常有趣的Javascript特效,能让网页上的图片飞起来:
- 解决Visual Studio 2008编译智能设备程序时找不到头文件的方法
- 20090204梦记
- 2009-02-05日志
- 介绍两个在DELPHI下支持接口的类
- Oracle之PL/SQL的变量小结
- flex 结合sandy引擎创作 (2)
- 吃掉IT大象:从绿海开发到棕海开发
- the stable version bboss-aop 1.0.4 released
- grep 使用
- 写在三十岁到来这一天
- MIME邮件面面观
- 09年又要死多少“第二款游戏”?