delphi - 为什么我的全局变量在调试时是 "inaccessible"?

标签 delphi variables global

我正在构建一个包含大约 30 个表单的应用程序。我需要管理 session ,因此我希望有一个可从所有表单访问的全局 LoggedInUser 变量。 我读过“David Heffernan”关于全局变量以及如何避免它们的文章,但我认为拥有一个全局 User 变量比 30 个拥有自己的 User 变量的表单更容易。

所以我有一个单位:GlobalVars

unit GlobalVars;

interface
uses User; // I defined my TUser class in a unit called User
var
   LoggedInUser: TUser;

implementation

initialization
   LoggedInUser:= TUser.Create;
finalization
   LoggedInUser.Free;
end.

然后在我的 LoginForm 的 LoginBtnClick 过程中我执行以下操作:

unit FormLogin;

interface

uses
  [...],User;

type
  TForm1 = class(TForm)
   [...]
    procedure LoginBtnClick(Sender: TObject);
  private
    { Déclarations privées }
  public
  end;

var
  Form1: TForm1;
  AureliusConnection : IDBConnection;

implementation

{$R *.fmx}
uses [...]GlobalVars;

procedure TForm1.LoginBtnClick(Sender: TObject);
var
  Manager : TObjectManager;
  MyCriteria: TCriteria<TUser>;
  u : TUser;
begin
  Manager := TObjectManageR.Create(AureliusConnection);
   MyCriteria :=Manager.Find<TUtilisateur>
    .Add(TExpression.Eq('login',LoginEdit.Text))
    .Add(TExpression.Eq('password',PasswordEdit.Text));
  u := MyCriteria.UniqueResult;
  if u = nil then
   MessageDlg('Login ou mot de passe incorrect',TMsgDlgType.mtError,[TMsgDlgBtn.mbOK],0)
  else begin
   LoggedInUser:=u;     //Here I assign my local User data to my global User variable
   Form1.Destroy;
   A00Form.visible:=true;
  end;
  Manager.Free;
end;

然后,我想以另一种形式在 Menu1BtnClick 过程中访问此 LoggedInUser 对象:

Unit C01_Deviations;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  FMX.ListView.Types, FMX.ListView, FMX.Objects, FMX.Layouts, FMX.Edit, FMX.Ani;

type
  TC01Form = class(TForm)
   [...]
Menu1Btn: TButton;
[...]
procedure Menu1BtnClick(Sender: TObject);

  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  C01Form: TC01Form;

implementation
uses [...]User,GlobalVars;
{$R *.fmx}

procedure TC01Form.Menu1BtnClick(Sender: TObject);
var
  Assoc : TUtilisateur_FonctionManagement;
  ValidationOK : Boolean;
  util : TUser;
begin
  ValidationOK := False;
  util := GlobalVars.LoggedInUser; // Here i created a local user variable for debug purposes as I thought it would permit me to see the user data. But i get "Inaccessible Value" as its value
  util.Nom:='test';
  for Assoc in util.FonctionManagement do  // Here is were my initial " access violation" error occurs
  begin
    if Assoc.FonctionManagement.Libelle = 'Reponsable équipe HACCP' then
    begin
      ValidationOK := True;
      break;
    end;
  end;
  [...]
end;

当我调试时,我在用户的值列中看到“不可访问的值”。你知道为什么吗?

我尝试在这个 GlobalVar 单元中放入一个整数,并且我能够从我的登录表单中设置它的值并从我的其他表单中读取它..

我想我可以存储用户的 id(一个整数),然后使用其 id 从数据库中检索用户。但看起来效率确实很低。

最佳答案

“我将此数据分配给我的全局用户” - 这是什么意思?

通过我的 Crystal 球,我在您的登录表单中看到与此类似的代码:

var
  user: TUser;
begin
  user := TUser.Create;
  try
    // assign properties/fields of user instance

    LoggedInUser := user;
  finally
    user.Free;
  end;
end;

之后,LoggedInUser 指向已释放(并且可能重用)的内存块。处理 LoggedInUser 的任何属性/字段都可能导致访问冲突。

哈,非常接近:

LoggedInUser:=u;

向您的 TUser 类添加一个方法 Assign(aSource: TUser),该方法对所有字段/属性的值进行深层复制(不是引用赋值)并调用相反:

LoggedInUser.Assign(u);

关于delphi - 为什么我的全局变量在调试时是 "inaccessible"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23996590/

相关文章:

java - 重命名所有变量和方法名称的脚本或工具有什么建议吗?

javascript - 如何在函数内部的全局上下文中定义javascript中的函数?

c++ - boost::python 混合嵌入/暴露:如何获取 globals() 并查看我自己的模块?

delphi - 使用 RTTI 加载 FireMonkey 风格的资源

delphi - 如何定义一个必须继承的基类?

c# - 在 C# 中加密字符串并在 Delphi 中解密

java - 在调用 .clear() 后,如何在 Java 中备份 ArrayList?

java - 变量多态性的初始化

c - C中的重复声明全局变量

delphi - 如何从代码中获取 ComboBox 的 SelectedValue?