退出RTTI相关函数后访问冲突:结果消失
Access violation after going out of a RTTI-related function: Result disappears
以前我有一个函数可以通过 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
对象成为全局变量。
以前我有一个函数可以通过 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
对象成为全局变量。