我写了这段代码:
FD := TList<double>.Create;
FN := TList<double>.Create;
RemList := TList<double>.Create;
dati := TStringList.Create;
try
try
//code
except
on E : Exception do
ShowMessage('Incorrect values. Error: ' + E.Message);
end;
finally
if Assigned(dati) then
dati.Free;
if Assigned(FD) then
FD.Free;
if Assigned(FN) then
FN.Free;
if Assigned(RemList) then
RemList.Free;
end;
我正在使用 firemonkey,因此当我在移动设备上运行它时不会出现问题,因为 ARC 将管理生命周期。但是当我在 Windows 上时,这段代码安全吗?
我读到我不能同时拥有一个finally和一个catch,所以我需要一个嵌套的try block 。我想最好的方法是这样的:
FD := TList<double>.Create;
try
FN := TList<double>.Create;
try
RemList := TList<double>.Create;
try
//and so on...
finally
Rem.Free;
end;
finally
FN.Free;
end;
finally
FD.Free;
end;
在这里,我确信在任何情况下我都会以安全的方式释放该对象,但代码很难阅读。我已经看到 Marco Cantu 在 object pascal 手册中建议使用第二种方法,我理解它,但就我而言,我想避免它。
我编写的第一个代码块会出现错误吗?
最佳答案
如果我是你,我会使用第二个代码块,因为你已经知道它更好; TList<double>.Create
(像其他构造函数一样)正如您所说的“安全”,但如果您始终假设角落后面存在风险,那就更好了。
请注意,当我说安全时,我的意思是如果您以这种方式调用它们,它们就不会引发异常。在您可能无法预测的任何情况下都可能发生异常,因此您确实应该通过 try finally 来保护代码。
您还使用 Assigned()
这是没用的。如果你看看 Free
的实现你会发现这段代码(也有注释):
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
if Self <> nil then
Destroy;
{$ENDIF}
end;
Assigned()
如果对象等于 nil 或不等于 nil,则返回 true 或 false,所以基本上你是在进行无用的双重检查。
关于Delphi 最后尝试多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42706510/