Delphi:TADoConnection变量赋值的引用与副本
我想了解Delphi是如何处理作业的。我有一个名为Delphi:TADoConnection变量赋值的引用与副本,delphi,variable-assignment,adoconnection,Delphi,Variable Assignment,Adoconnection,我想了解Delphi是如何处理作业的。我有一个名为GlobalConn(TADoConnection)的全局连接 我有一个函数,它使用传入的变量进行数据库调用: function MakeDBCall( AConnection : TAdoConnection ) var LocalConn : TAdoConn; begin LocalConn := TAdoConnection.Create(nil); try LocalConn := AConnection
GlobalConn
(TADoConnection
)的全局连接
我有一个函数,它使用传入的变量进行数据库调用:
function MakeDBCall( AConnection : TAdoConnection )
var LocalConn : TAdoConn;
begin
LocalConn := TAdoConnection.Create(nil);
try
LocalConn := AConnection
///create the table and perform action using the LocalConn
finally
LocalConn.free;
end;
end;
调用将使用MakeDbCall
(GlobalConn
)
LocalConn:=a连接(在函数内部)时,实际会发生什么情况?引用计数是增加了还是为局部变量分配了一个新副本
LocalConn
是否会影响GlobalConn
谢谢您的代码没有您认为的功能。我写了一些评论,试图解释到底发生了什么
function MakeDBCall( AConnection : TAdoConnection )
var
LocalConn : TAdoConn;
begin
// This creates a brand new ADO connection.
LocalConn := TAdoConnection.Create(nil);
try
// This line discards the connection you've just created,
// orphaning it (leaking the memory), and sets LocalConn
// to point to the object passed in as AConnection.
LocalConn := AConnection
///create the table and perform action using the LocalConn
finally
// This line frees AConnection, making your global variable invalid
LocalConn.free;
end;
end;
因此,要直接回答您提出的问题:
LocalConn
将成为指向a连接的新变量,而不是副本TADOConnection
不是接口,因此不受引用计数的约束。没有分配新副本-LocalConn
只是指向传递给函数的连接实例的另一个变量
释放LocalConn是否会影响GlobalConn
对。它释放了a连接
,使对它的任何引用无效,可能是您的全局连接实例。(它对您使用TADOConnection.Create(nil)
创建的本地连接没有任何影响;该内存会泄漏,因为您丢弃了可用于释放它的唯一对它的引用
理想情况下,我假设复制比获取连接字符串并分配给局部变量并打开更好(更快)……这是正确的假设吗
可能是,如果你真的在复制,但你不是
这与Delphi 7和XE7-Xe10的处理方式不同吗
不。我在上面指出的是,从v1开始,在处理VCL和Windows时,Delphi的每个版本都是相同的。(移动设备上的FMX改变了一些事情,但它不会改变仍然错误地释放全局对象的事实。)
如果TADOConnection
实际实现了Assign
方法,您可以使用它。但是,文档中不清楚是否实现了该方法;文档链接到TPersistent.Assign
。您可以查看实际使用的Delphi版本的源代码(我在这台笔记本电脑上没有D2007)查看是否已实现。如果已实现,您可以使用以下内容:
LocalConn := TADOConnection.Create(nil);
try
LocalConn.Assign(AConnection);
// Use LocalConn
finally
LocalConn.Free; // Frees the local copy
end;
为什么要这样做,而不仅仅是使用AConnection本身?对TAdoConnection.Create的调用会在堆上创建一个新实例。通过将LocalConn分配给AConnection,然后通过LocalConn.Free对AConnection有效地调用Free,可以有效地丢弃该实例。因此,当您的过程退出时,您已经释放了错误的对象并创建了一个新实例由于丢弃您创建的TAdoConnection对象而导致内存泄漏。它不能像您想象的那样工作,您正在用全局变量覆盖局部变量(从而泄漏本地创建的连接)最后,您将释放全局变量,从而在下次使用全局变量时生成一个AV…@WHOSRDADY:说得好!大家好-谢谢您的评论。让局部变量使用现有变量(全局变量已打开)的“副本”的最佳方式是什么连接-无需打开新连接?当我说“打开”意味着创建一个新的连接对象并设置connectionstring然后打开时。我的假设是多次打开连接会产生一些延迟时间。感谢您提供的信息和建议。我的困惑是因为没有意识到当使用了信号“操作员”。这是一个指向Embarcadero人员的链接,增加了我的理解:。