gpt4 book ai didi

delphi - 将 _Recordset 结果与 TADOConnection.Execute 函数结合使用

转载 作者:行者123 更新时间:2023-12-02 00:46:14 25 4
gpt4 key购买 nike

TADOConnection.Execute 函数返回一个 _Recordset

为了简单起见,我目前使用此代码(1):

V := ADOConnection1.Execute(SQL).Fields[0].Value;

我知道记录集永远不会为空,所以不用担心BOF

现在我可以使用本地 _Recordset 变量(2)这样编写它。

var
rs: _Recordset;

rs := ADOConnection1.Execute(SQL);
V := rs.Fields[0].Value;

更多代码。

现在我的问题是:由于_Recordset是Execute函数返回的接口(interface)变量,如果我不使用本地rs,它会被正确释放吗> 变量 (1)?使用我的简化代码(1)是否安全,这里可能存在引用计数问题吗?

我想了解有关此问题的一些见解。

<小时/>

编辑:我的问题是针对具体案例的:

V := ADOConnection1.Execute(SQL).Fields[0].Value

其中我没有对 _Recordset 的局部变量引用。

最佳答案

试试这个:创建一个包含单行的过程

  V := AdoConnection1.Execute(Sql).Fields[0].Value;

,在其上放置断点运行应用程序并查看反汇编结果。您会在该行之前看到它

jmp @HandleFinally

有 3 个调用

call @IntfClear

这是编译器释放它必须访问的三个接口(interface)才能执行该语句,即

  • AdoConnection1.Execute() 返回的 RecordSet 接口(interface),
  • 该 RecordSet 的 Fields 接口(interface),以及
  • 通过 Fields[0] 获得的特定 Field 接口(interface)。

因此,它在执行源语句后自动生成了释放这些接口(interface)所需的代码。

下面是一个不完美的类比,但它的反汇编更容易理解;它说明了编译器自动生成的用于处理终结接口(interface)的代码。

给定

type
IMyInterface = interface
function GetValue : Integer;
end;

TMyClass = class(TInterfacedObject, IMyInterface)
function GetValue : Integer;
destructor Destroy; override;
end;

TForm1 = class(TForm)
[...]
procedure Button1Click(Sender: TObject);
end;

destructor TMyClass.Destroy;
begin
inherited;
end;

function TMyClass.GetValue: Integer;
begin
Result := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
I : IMyInterface;
begin
I := TMyClass.Create;
Caption := IntToStr(I.GetValue);
end;

Button1Click的CPU拆解如下

disassembly

红色箭头线是界面被清除的地方,尽管有源代码没有做任何明确的事情来做到这一点。打断点

inherited

在 TMyClass.Destroy 中,你会发现它也会被调用,尽管源代码没有显式调用它。

正如我所说,以上是一个不完美的类比。有趣的是,对于可怕的(从使用“with”结构的角度来看)替代方案

procedure TForm1.Button1Click(Sender: TObject);
begin
with IMyInterface(TMyClass.Create) do
Caption := IntToStr(GetValue);
end;

不使用(显式)局部变量,编译器生成与反汇编所示的完全相同代码。

当然,q中的情况略有不同,因为分配给记录集对象的内存位于Ado COM接口(interface)的另一侧,因此人们无法控制该内存是否被正确地解除分配。编译器将生成代码以在其接口(interface)上调用 _Release。

关于delphi - 将 _Recordset 结果与 TADOConnection.Execute 函数结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32049222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com