退出 RTTI 相关函数后发生访问冲突:结果消失

Pau*_*aul 2 delphi rtti

以前我有一个函数可以通过 RTTI 获取对象属性并设置它的值。现在我决定将其拆分为TRTTI.GetObjPropTRTTI.SetObjPropValue,以便缓存返回的值TRTTI.GetObjProp并加快数据处理速度。

之后发生了奇怪的事情。首先,我突然注意到它ctx.GetType有效并且一直有效,尽管我从未初始化过该ctx变量。好吧,如果我用 初始化它TRttiContext.Create(),第二个奇怪的地方没有任何变化:

我调用该TRTTI.GetObjProp函数,只要我在该函数中,Result就已定义,并且我可以使用调试器请求它的属性。当我退出该函数时,我尝试请求rprop变量的相同属性并收到访问冲突错误。根据调试器,rprop已定义。

procedure TConfManager._setValue(indicator: TComponent; name: string; value: OleVariant);
var
  rprop: TRttiProperty;
begin
  rprop := TRTTI.GetObjProp(indicator, name);
  //Access violation here when I try to use rprop
  TRTTI.SetObjPropValue(indicator, rprop, value);
end;

class function TRTTI.GetObjProp(obj: TObject; propName: string): TRttiProperty;
var
  ctx: TRttiContext;
  rtyp: TRttiType;
begin
  if obj = nil then Exit(nil);
  rtyp := ctx.GetType(obj.ClassType);
  Result := rtyp.GetProperty(propName);
end;
Run Code Online (Sandbox Code Playgroud)

为什么当我在函数中时函数结果被正确定义,但当我离开函数时却没有正确定义?

Dav*_*nan 5

实例TRttiProperty由对象拥有TRttiContext。当局部变量ctx离开作用域时,该TRttiContext对象将被销毁,并带走它拥有的所有对象,包括您的TRttiProperty实例。

您需要确保TRttiContext拥有您使用的任何 RTTI 对象的对象的生命周期至少与对这些拥有的对象的任何引用一样长。实现这一点的最简单方法可能是使TRttiContext对象成为全局变量。