6

我对 Delphi 有一个基本的疑问。当我在设计时保留任何组件时,例如 TADOConnectuion 并单击按钮,即使我编写以下代码,我也不会收到任何错误:

begin
  ADOConnection.Free;  //No error
  ADOConnection.Free;  //No error
  ADOConnection.Free;  //No error
end;

但是,如果我在运行时创建与以下相同的对象,则会收到“访问冲突...”错误

begin
  ADOConnection := TADOConnection.create(self);
  ADOConnection.Free;  //No error
  ADOConnection.Free;  //Getting an "Access Violation..." error
end;

即使我创建如下对象,我也会收到相同的错误:

ADOConnection := TADOConnection.create(nil);

只是想知道这种行为背后的原因,即为什么我在设计时保留组件时没有错误?

4

2 回答 2

4

如果释放组件,则其在所有者中的相应字段将被清除。如果添加 design-time ADOConnection,那么

ADOConnection.Free; // Frees ADOConnection and sets ADOConnection to nil
ADOConnection.Free; // Does nothing since ADOConnection is nil

您可以通过在变量中捕获它来查看它:

var c: TADOConnection;
c := ADOConnection;
c.Free; // Frees ADOConnection and sets ADOConnection to nil
c.Free; // Error: c is not set to nil

ADOConnection即使在设计时创建,那也行不通。

这是一个TButton组件示例,它演示了您在设计时组件中看到的行为并非特定于设计时组件:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  published
    Button: TButton;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Assert(not Assigned(Button));
  TButton.Create(Self).Name := 'Button'; // Button field gets set
  Assert(Assigned(Button));
  Button.Free;                           // Button field gets cleared
  Assert(not Assigned(Button));
  Button.Free;                           // Okay, Free may be called on nil values
end;

end.
于 2012-08-30T09:03:36.823 回答
3

ADOConnection 最初是 nil,所以如果你释放它,free 函数不会做任何事情,因为传递给它的指针是 nil。在随后的调用中,指针保持为 nil,因此 free 继续什么都不做。当你用 create 初始化 ADOConnection 时,ADOConnection 中持有的指针不再是 nil,所以第一次调用 free 会主动释放指针,但后续调用会看到内存已经被释放并引发异常。调用 free 不会更改指针。为此,您需要 freeandnil 代替。

于 2012-08-30T08:58:14.043 回答