以前,我有一个函数可以通过RTTI获取对象属性并设置其值。现在,我决定将其拆分为TRTTI.GetObjProp
和TRTTI.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;
为什么在使用函数时正确定义了函数结果,而退出函数时却没有正确定义?
最佳答案
TRttiProperty
实例归TRttiContext
对象所有。当局部变量ctx
离开作用域时,该TRttiContext
对象将被销毁,并带有它拥有的所有对象,包括您的TRttiProperty
实例。
您需要确保拥有使用的任何RTTI对象的TRttiContext
对象的生存时间至少与对这些拥有对象的任何引用一样长。最简单的实现方法可能是使TRttiContext
对象成为全局变量。