簡體   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