【发布时间】:2019-03-09 04:51:25
【问题描述】:
我在过程中有一个变量,我需要在该过程中的匿名方法运行之前保持活动状态,但我不在匿名方法中使用该变量。有没有一种惯用的方法告诉编译器无论如何都要捕获变量?
例如:
procedure ForceCapture(const AVar);
begin
// No-op
end;
procedure TMyClass.MyProcedure;
var
Rec: TSearchRec;
begin
CallAnonMethod(@Rec,
procedure(retVal: Integer);
begin
ForceCapture(Rec); // What should this be?
if retVal = 0 then ...
end;
end;
以上方法适用于 Win32,但我担心 LLVM 后端或未来的一些优化会识别 ForceCapture 不执行任何操作并将捕获作为空操作删除。在这种情况下,CallAnonMethod 必须接受一个指针,而不是一个引用,因此在其中制作副本不是一种选择。
【问题讨论】:
-
你无法保证未来不会改变,别以为你能做得比这更好。
-
@loki 问的问题与 ARC 完全无关。
-
@loki 首先,ARC 是让事物在必要时保持活力的东西。因此,如果有人需要让事情保持活力,你可以打赌他们不会谈论 ARC。如果您仔细阅读,您会看到匿名方法需要一个指向 TSearchRec 的指针——它是记录而不是对象,因为它是在堆栈上创建的,它会在 MyProcedure 完成后立即失效。显然,问题中的匿名方法的寿命比这更长,并且需要捕获该变量 - 使其保持活力。看不到 ARC - 除非您将 ARC 计算在所有编译器中都存在的匿名方法后面。
-
@Dalija - 请原谅我的无知,匿名程序怎么可能比 MyProcedure 寿命更长?它是异步运行的吗?否则,AFAICS、CallAnonProc 在执行匿名过程之前不会返回。
-
@SertacAkyuz 如果它不能超过 MyProcedure,那么首先就没有问题需要解决。关键是它可能比 MyProcedure 寿命更长,只是问题中没有提供可以使其保持活力的那部分代码。