繁体   English   中英

Delphi AV 在自定义 class 中使用 TStringList 时

[英]Delphi AV when using TStringList in a custom class

在 Delphi Rio 中,我创建了一个 class,其目的是从数据库中读取记录。 这条记录是纯只读的,看完之后还需要推导一些额外的属性。 我的问题与我想在 class 定义中使用的字符串列表有关。 我有一个名为 fVENDORS_TO_COLORCODE 的私有 class 成员。 这是一个逗号分隔的字符串。 我想做一个 TStringlist 的属性。 我正在使用 TStringList.CommaToText 将我的值加载到 Tstringlist 中。 我在 Create Constructor 中执行此操作。 我遇到的问题是,虽然 StringList 在构造函数中有效,但在构造函数之外它是 nil ,我不知道我做错了什么。 这是代码的相关部分。

type
  TProfileDef = class(TObject)
  private
    fNAME: String;   
    fVENDORS_TO_COLORCODE: String;  // incoming comma separated string. Example string:  Microsoft,IBM
    fVENDORS_TO_COLORCODE_SL : TStringList;
    ..

  public  
    constructor Create(ProfileName: String); 
    destructor Destroy; override;   
  published   
    property NAME: String read fNAME;  
    property VENDORS_TO_COLORCODE: String read fVENDORS_TO_COLORCODE;
    property VENDORS_TO_COLORCODE_SL : TStringList read fVENDORS_TO_COLORCODE_SL;  
    ..
  end;

implementation

destructor TProfileDef.Destroy;
begin
inherited;
  fVENDORS_TO_COLORCODE_SL.Free;
end;


constructor TProfileDef.Create(ProfileName: String);
var
  fVENDORS_SL: TStringList;
  fVENDORS_TO_COLORCODE_SL: TStringList;
  TempVendorList : String;

begin
inherited Create;
fName := ProfileName;

.. [Find my record based on ProfileName, and load the DB columns into the private variables]..

    // Load the Color Code String into a StringList;
    fVENDORS_TO_COLORCODE_SL := TStringList.Create;   
    fVENDORS_TO_COLORCODE_SL.CommaToText :=  fVENDORS_TO_COLORCODE; 
end;

在构造函数中,创建了 fVENDORS_TO_COLORCODE_SL 字符串列表,并添加了数据......问题是当我尝试使用它时......

var
TestClass: TProfileDef;
begin
TestClass := TProfileDef.Create('Sample Profile');
// TestClass.Name is valid
// TestClass.VENDORS_TO_COLORCODE_SL is nil, and trying to access gives AV

不知何故,我定义了这个错误,但我无法确定它是什么,以便纠正它。

您的 class 有一个私有字段

fVENDORS_TO_COLORCODE_SL: TStringList;

您的构造函数应该创建一个TStringList object 并让这个变量指向它。 我认为这是你的意图,至少。 但是,您的构造函数有一个同名的局部变量fVENDORS_TO_COLORCODE_SL ,所以该行

fVENDORS_TO_COLORCODE_SL := TStringList.Create;  

确实创建了一个TStringList object,但是指针保存到了这个局部变量,类的同名字段保持为nil

解决方法:去掉构造函数中局部变量的声明。

// Load the Color Code String into a StringList;
fVENDORS_TO_COLORCODE_SL := TStringList.Create;   

构造函数中的这一行是问题所在。 您有两个名为fVENDORS_TO_COLORCODE_SL的变量。 一个是在 class 声明的private部分中声明的 class 的私有成员,另一个是在构造函数的var部分中声明的局部变量。
猜猜哪个优先。 没错,就是构造函数中的局部变量。 该行初始化了名为fVENDORS_TO_COLORCODE_SL的局部变量,同名的私有 class 成员仍然是nil 作为一般规则,我在方法中以 l 开头局部变量,并且仅在 class 成员前面加上 f 以避免此类问题。 在构造函数中重命名局部变量,如下所示:

constructor TProfileDef.Create(ProfileName: String);
var
  lVENDORS_SL: TStringList;
  lVENDORS_TO_COLORCODE_SL: TStringList;
  lTempVendorList : String;
begin

然后更新您的代码并重建。 事情应该很快就会变得显而易见。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM