调试时为什么我的全局变量"无法访问"?

Ant*_*Lpy 6 delphi variables global

我正在构建一个包含大约30个表单的应用程序.我需要管理会话,所以我希望可以从所有表单访问全局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.
Run Code Online (Sandbox Code Playgroud)

然后在我的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;
Run Code Online (Sandbox Code Playgroud)

然后在另一种形式,我想在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;
Run Code Online (Sandbox Code Playgroud)

当我调试时,我在用户的值列中看到"Inaccessible Value".你知道为什么吗?

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

我想我可以存储用户的id,这是一个整数,然后使用其id从数据库中检索用户.但它似乎真的很无效.

Igo*_*gor 5

"我将这些数据分配给我的全球用户" - 这是什么意思?

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

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

    LoggedInUser := user;
  finally
    user.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

之后,LoggedInUser指向释放(并且可能重用)内存块.解决任何财产/领域LoggedInUser可能会导致访问违规.

哈,非常接近:

LoggedInUser:=u;
Run Code Online (Sandbox Code Playgroud)

Assign(aSource: TUser)向您的TUser类添加一个方法,该方法为所有字段/属性(不是引用分配)执行值的深层复制,并改为调用它:

LoggedInUser.Assign(u);
Run Code Online (Sandbox Code Playgroud)

  • 你在哪里拿到水晶球?它似乎有很大的力量. (3认同)