gpt4 book ai didi

Delphi 异常处理 - 如何正确清理?

转载 作者:行者123 更新时间:2023-12-03 14:41:53 27 4
gpt4 key购买 nike

我正在查看我们的应用程序中的一些代码,发现了一些与我通常所做的有点奇怪的事情。对于异常处理和清理,我们(我确信还有许多其他程序员)使用嵌入了 Try/Except block 的 Try/Finally block 。现在我已经习惯了 Try/Finally 中的 Try/Except,如下所示:

Try
Try
CouldCauseError(X);
Except
HandleError;
end;
Finally
FreeAndNil(x);
end;

但是另一个代码块是相反的:

Try
Try
CouldCauseError(X);
Finally
FreeAndNil(x);
end;
Except
HandleError;
end;

环顾网络,我看到人们以两种方式这样做,但没有解释原因。我的问题是,哪个获得外部 block 、哪个获得内部 block 有关系吗?或者无论它的结构方式如何, except 和finally 部分都会得到处理吗?谢谢。

最佳答案

一个区别是 try..finally.. except 可能容易受到异常屏蔽情况的影响。

想象一下 CouldCauseError() 中发生异常。然后想象一下 finally 中对 FreeAndNIL(X) 的尝试会导致进一步的异常。原始异常(很可能导致不稳定,导致 FreeAndNIL() 异常)丢失。 除了处理程序现在正在处理在原始异常之后发生的“下游”异常。

try.. except..finally 当然可以避免这种情况,因此应该是首选(处理异常尽可能接近其来源)。

处理此类简单情况(正在清理的单个对象)的另一种方法是在异常处理程序中的正常流程中包含清理:

try
CouldCauseError(X);
FreeAndNil(x);
except
HandleError;
FreeAndNil(x);
end;

一开始这看起来有点吓人(“我需要确定FreeAndNIL(X)被调用,所以我必须有一个最终!!”)但第一个 FreeAndNIL() 可能不会被调用的唯一方法是,如果有异常,并且如果有异常,那么无论如何你也会使用 FreeAndNIL() ,并且它会执行清理的顺序在发生异常的情况下更清晰一些(从消除噪音的意义上来说,在某种程度上必须“过滤”掉噪音才能了解正在发生的事情)。

但是,我个人不喜欢它 - 如果您更改异常处理程序或正常流程中的代码,您将面临破坏清理行为的风险,但这取决于此类 block 周围的代码以及 block 本身的大小,为了简化起见,在某些情况下可以认为减少“噪音”是合理的。

但是,这依赖于以下事实:FreeAndNIL() 实际上是“NILThenFree()”...X 是 NIL'd在它被 Free 之前,所以如果在正常流程中 FreeAndNIL(X) 中发生异常,那么当异常处理程序捕获 X.Free 引发的异常时,X 将为 NIL ,因此它不会尝试“双重释放”X。

无论您决定什么,我希望对您有所帮助。

关于Delphi 异常处理 - 如何正确清理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2473575/

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