在Delphi中编程时,通常不需要动态创建组件。如果将组件拖放到表单上,Delphi将在创建表单时自动处理组件创建。本文将介绍在运行时以编程方式创建组件的正确方法。
有两种方法可以动态创建组件。一种方法是使表单(或其他某个TComponent)成为新组件的所有者。在可视化容器创建并拥有子组件的情况下构建复合组件时,这是一种常见做法。这样做将确保在销毁所属组件时销毁新创建的组件。
要创建类的实例(对象),可以调用其“create”方法。Create构造函数是一个类方法,与Delphi编程中遇到的几乎所有其他方法(对象方法)相反。
例如,TComponent声明Create构造函数如下:
构造函数创建(AOwner:TComponent);事实上的
具有所有权的动态创建这是一个动态创建的示例,其中Self是TComponent或TComponent后代(例如,TForm的实例):
使用TTimer.Create(Self)dobeginterval:=1000;已启用:=假;OnTimer:=MyTimerEventHandler;结束;
通过显式调用free动态创建创建组件的第二种方法是使用nil作为所有者。请注意,如果执行此操作,还必须在不再需要创建的对象时立即显式释放该对象(否则将产生内存泄漏)。以下是使用nil作为所有者的示例:
使用TTable.Create(nil)dotryDataBaseName:=“MyAlias”;TableName:=“MyTable”;打开编辑FieldByName('Busy')。AsBoolean:=True;邮递最终自由;结束;
动态创建和对象引用通过将创建调用的结果分配给方法的局部变量或属于类的变量,可以增强前面的两个示例。当以后需要使用对组件的引用时,或者当需要避免“With”块可能导致的范围界定问题时,这通常是可取的。下面是上面的TTimer创建代码,使用字段变量作为对实例化TTimer对象的引用:
FTimer:=TTimer.Create(Self);带FTimer的多贝吉神经:=1000;已启用:=假;OnTimer:=MyInternalTimerEventHandler;结束;
在本例中,“FTimer”是表单或可视容器(或任何“Self”是什么)的私有字段变量。当从此类中的方法访问FTimer变量时,最好先检查引用是否有效,然后再使用它。这是使用Delphi指定的功能完成的:
如果已分配(FTimer),则FTimer.Enabled:=True;
没有所有者的动态创建和对象引用这方面的一个变体是创建没有所有者的组件,但保留引用以备将来销毁。TTimer的构造代码如下所示:
FTimer:=TTimer.Create(无);和多贝金一起…结束;
销毁代码(可能在表单的析构函数中)看起来像这样:
FTimer.Free;FTimer:=nil;(*或使用FreeAndNil(FTimer)过程,释放对象引用并用nil.*替换引用)
释放对象时,将对象引用设置为nil非常关键。对Free的调用首先检查对象引用是否为nil,如果不是,则调用对象的析构函数Destroy。
下面是上面的TTable创建代码,使用局部变量作为对实例化TTable对象的引用:
localTable:=TTable.Create(nil);trywith localTable dobeginadabasename:=“MyAlias”;TableName:=“MyTable”;结束;../稍后,如果我们想显式指定作用域:localTable.Open;localTable.Edit;localTable.FieldByName('Busy')。AsBoolean:=True;localTable.Post;最终可计算。免费;localTable:=nil;结束;
在上面的示例中,“localTable”是在包含此代码的同一方法中声明的局部变量。请注意,释放任何对象后,通常最好将引用设置为nil。
重要提示:不要将对Free的调用与向构造函数传递有效的所有者混为一谈。前面的所有技术都将起作用,并且都是有效的,但在您的代码中不应出现以下情况:
用TTable.Create(self)dotry…最终释放;结束;
上面的代码示例引入了不必要的性能影响,对内存有轻微影响,并且有可能引入难以发现的bug。找出原因。
注意:如果动态创建的组件具有所有者(由Create构造函数的AOwner参数指定),则该所有者负责销毁该组件。否则,当不再需要该组件时,必须显式调用Free。
文章最初由马克·米勒撰写
在Delphi中创建了一个测试程序,以确定1000个具有不同初始组件计数的组件的动态创建时间。测试程序出现在本页底部。图表显示了测试程序的一组结果,比较了创建有所有者和无所有者组件所需的时间。请注意,这只是命中的一部分。销毁组件时,可能会出现类似的性能延迟。根据表单上的组件数量和正在创建的组件,动态创建具有所有者的组件的时间比创建没有所有者的组件的时间慢1200%到107960%。
警告:此测试程序不会跟踪和释放在没有所有者的情况下创建的组件。通过不跟踪和释放这些组件,为动态创建代码测量的时间可以更准确地反映动态创建组件的实时性。
下载源代码
如果您想动态实例化一个Delphi组件,并在以后显式释放它,请始终将nil作为所有者传递。不这样做可能会带来不必要的风险,以及性能和代码维护问题。阅读“动态实例化Delphi组件的警告”文章了解更多。。。
...端脚本语言,在网页中提供交互效果,使网站看起来更具动态性。它是一种在网络浏览器中运行的功能齐全的编程语言。另一方面,AngularJS(也称为Angular)是一个基于JavaScript的框架,它用新的属性扩展HTML,专门设计用于构建动...
...性稳步增加。那时,只使用JavaScript API就可以创建高级的动态web应用程序,但是很难维护初始的代码库。JavaScript通过允许脚本在浏览器中运行,开创了web应用程序开发的一场革命,并成为一种功能强大、功能齐全的编程语言。201...
....NET Framework的一个web应用程序部分,用于创建数据驱动、动态、可扩展性好的网站,并且可以在各种网站上正常工作,而无需开发人员进行任何自定义编码。 .NET和ASP.NET中的工具和库 .NET Framework使用一组编程语言,包括C++语言...
...架,而ASP.NET是一个web框架,它是.NET的一部分,允许构建动态web应用程序。 .NET framework面向各种平台,包括移动、嵌入式系统、操作系统和web浏览器插件。此外,它还提供了与许多编程语言的互操作性,提高了安全性,提供了自...
...成可执行的二进制文件,它需要一个外部源,比如Word。动态链接库VB可以利用动态链接库实现构件对象模型程序。VBA没有创建可以使用DLL的程序的规定。程序类型VB可以创建独立的应用程序,并且有编译器可以这样做。VBA无法创...
...XE和DLL也是一种文件扩展名,人们经常混淆。执行(exe) vs. 动态链接库(dll)EXE和DLL的区别在于,EXE文件可以在操作系统的帮助下执行。他们不需要任何其他应用程序来运行。另一方面,DLL文件不是独立运行的。它们需要一个EXE文件...
...定类型的程序或软件来打开这些类型的文件。库(lib) vs. 动态链接库(dll)LIB和DLL的区别在于,DLL文件是可重用的,因为它们只需要链接到以前的DLL,而LIB不具备这种质量,代码必须从以前的程序复制到新的程序。另一个区别是LIB是...
...传统的html进行了调整和扩展,使用双向数据绑定来呈现动态数据。 angular是建立在这样一种思想上的:声明式编程应该用来创建用户界面和连接软件组件。angular将焦点从dom操作转移到模型和视图的自动同步。angular的优点在于,...
...执行其他CGI程序可以执行的任何任务,但它主要用于创建动态Web页面。它的主要优点是与多种类型的数据库兼容。此外,PHP可以使用IMAP、SNMP、NNTP、POP3或HTTP在网络上进行通信。 PHP包含命令行界面功能,可以在独立的图形应用程...
...oft开发和发布的服务器端脚本环境。它是微软第一个用于动态生成网页的服务器端脚本引擎。ASP最初是作为WindowsNT4.0选项包的一部分发布的。它本来是Internet信息服务(IIS)的一个附加组件。从那时起,ASP被微软的另一个产品ASP....