首页 > 解决方案 > 退出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;

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

标签: delphirtti

解决方案


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

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


推荐阅读