我从该单元获取访问权限DBXCommon.pas(在Delphi XE中).当我查看代码时,我会看到以下内容(在感叹号处):
function TDBXConnectionFactory.GetConnection(const DBXContext: TDBXContext;
const ConnectionProperties: TDBXProperties): TDBXConnection;
var
ConnectionBuilder: TDBXConnectionBuilder;
DelegatePath: TDBXDelegateItem;
Connection: TDBXConnection;
CombinedProperties: TDBXProperties;
begin
//...
ConnectionBuilder := TDBXConnectionBuilder.Create;
Connection := nil;
try
//..lots of setting ConnectionBuilder properties
ConnectionBuilder.FInputPassword := CombinedProperties[TDBXPropertyNames.Password];
Connection := ConnectionBuilder.CreateConnection;
Connection.Open;
Result := Connection;
!! Connection := nil;
finally
!! Connection.Free;
ConnectionBuilder.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
但我看到这样的结构(首先分配Nil,然后是免费)DBXCommon.pas.这是一些我不知道的构造,或者每次调用这段代码时这是否真的导致访问冲突?
Rob*_*edy 15
调用Freenull引用始终是安全的.去看看执行情况TObject.Free,看看为什么.
此代码是工厂函数的示例.它的工作是创建一个类的新实例,但是如果它失败了,它需要确保它在抛出异常时不会泄漏半创建的实例,因此它会调用Free.当它确定它会成功时,它会将结果的所有权转移给调用者.它仍然会调用Free,但如果它已经转移了所有权,那么它最终会调用Free一个空引用,并且没有任何损害.此代码转移所有权:
Result := Connection;
Connection := nil;
Run Code Online (Sandbox Code Playgroud)
顺便我会写一个工厂函数将废除独立的Connection变量.我直接构造了结果Result,但如果有异常,请将其释放,如下所示:
function TDBXConnectionFactory.GetConnection(const DBXContext: TDBXContext;
const ConnectionProperties: TDBXProperties): TDBXConnection;
var
ConnectionBuilder: TDBXConnectionBuilder;
DelegatePath: TDBXDelegateItem;
Connection: TDBXConnection;
CombinedProperties: TDBXProperties;
begin
//...
ConnectionBuilder := TDBXConnectionBuilder.Create;
try
//..lots of setting ConnectionBuilder properties
ConnectionBuilder.FInputPassword := CombinedProperties[TDBXPropertyNames.Password];
Result := ConnectionBuilder.CreateConnection;
try
Result.Open;
except
Result.Free;
raise;
end;
finally
ConnectionBuilder.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这具有相同的效果.
它是安全的调用Free上nil的参考,因为它的实施检查Self <> nil之前调用Destroy.见艾伦·鲍尔在解释Embarcadero的论坛为什么TObject.Free被引入.我在这里只包括相关的引用:
在TObject上引入非虚拟Free方法的唯一原因是在析构函数中使用它作为简单的简写:
if FField <> nil then
FField.Destroy;
Run Code Online (Sandbox Code Playgroud)