Delphi RTTI属性内存异常求助:新项目中引用莫名失效
解决RTTI属性引用在新项目中变为nil的问题
以下是针对你遇到的RTTI引用失效问题的排查和解决方向:
1. 检查RTTI上下文的生命周期
Delphi的TRttiProperty等RTTI对象依赖于创建它们的TRttiContext实例存活,若上下文被提前销毁,所有从它获取的RTTI引用都会失效。
- 错误示例(局部上下文导致引用失效):
procedure FillPropertyMap; var LocalContext: TRttiContext; Prop: TRttiProperty; begin LocalContext := TRttiContext.Create; for Prop in LocalContext.GetType(TYourEntity).GetProperties do FMap.Add(Prop, TMappedField.Create); LocalContext.Free; // 上下文销毁后,Prop引用全部变为无效 end; - 正确做法:将
TRttiContext声明为类成员或全局实例,确保在使用RTTI引用期间上下文始终存在:type TEntityMapper = class private FRTTIContext: TRttiContext; FMap: TDictionary<TRttiProperty, TMappedField>; FPropertyPK: TRttiProperty; public constructor Create; procedure BuildPropertyMap; end; constructor TEntityMapper.Create; begin inherited; FRTTIContext := TRttiContext.Create; FMap := TDictionary<TRttiProperty, TMappedField>.Create; end; procedure TEntityMapper.BuildPropertyMap; var Prop: TRttiProperty; begin for Prop in FRTTIContext.GetType(TYourEntity).GetProperties do begin // 处理属性并填充FMap、FPropertyPK end; end;
2. 确认RTTI生成开关配置
即使同步了编译选项,仍需检查目标类所在单元的RTTI指令:
- 确保单元开头有正确的RTTI声明,比如:
{$RTTI EXPLICIT METHODS([vcPublic, vcProtected]) PROPERTIES([vcPublic, vcProtected]) FIELDS([vcPublic])} - 验证项目编译选项:在
Project Options > Delphi Compiler > Compiling中,确认Runtime Type Information处于开启状态,且选项覆盖范围包含目标类单元。
3. 排查类元数据的生命周期
如果目标类来自动态加载的包或DLL,需确保:
- 包/DLL未被提前卸载,否则类的元数据会被释放,导致RTTI引用失效。
- RTTI上下文在同一个模块中创建,避免跨模块的RTTI引用问题。
4. 检查赋值逻辑的正确性
- 确认填充FMap和FPropertyPK时,没有误操作导致引用被覆盖或释放。比如是否在填充后调用了
TRttiContext.Free,或对TRttiProperty变量进行了不当赋值。 - 确保FPropertyPK的赋值来自同一个有效RTTI上下文的返回值,而非临时变量的无效副本。
5. 启用内存检测定位问题
在新项目中启用FastMM的完整调试模式:
- 将
FastMM4.pas添加到项目的uses列表,开启FullDebugMode,它会捕获内存越界、提前释放等问题,帮助定位引用失效的具体触发点。
内容的提问来源于stack exchange,提问作者missingNO
相关产品推荐
相关产品推荐

