我正在构建一个包含大约 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/