Datasnap和TObject引用

时间:2012-05-16 09:00:48

标签: delphi delphi-xe2 datasnap

如何在datasnap服务器中处理对象引用?

我有Datasnap服务器方法,它返回TUser对象

TServerMethods.CurrentUser(const AId: Integer): TUser
begin
  Result := GlobalCurrentUser; // <- Don't want to free this object
  Result.AddReference;
end;

TReferencedObject的子类中的TUser

TReferencedObject = class(TObject)
private
  FReferenceCnt:     integer;
public
  procedure AddReference; virtual;
  procedure RemoveReference; virtual; // Frees object if reference count goes to 0
  property ReferenceCnt: integer Read FReferenceCnt Write FReferenceCnt;
end;

目前DataSnap服务器释放TUser对象,但我想为TReferencedObject后代调用RemoveReference。

1 个答案:

答案 0 :(得分:1)

我将DataSnap文件Data.DBXJSONReflect.pas和Datasnap.DSReflect.pas复制到项目目录,添加到项目并进行了三次修改。

Data.DBXJSONReflect中的两处更改以设置正确的ReferenceCount

1)TJSONUnMarshal.CreateObject

  if HasObject(ObjId) then
  begin
    Obj := GetObject(ObjId);
    if Obj is TReferencedObject then {Framework}
      TReferencedObject(Obj).AddReference; {Framework}    
    exit(Obj);
  end

2)TJSONPopulationCustomiser.PostPopulate

  if Data is TReferencedObject then {Framework}
    TReferencedObject(Data).AddReference; {Framework}

Datasnap.DSReflect中的一项更改以发布参考

1)TDsMethodValues.ClearReferenceParameters

FUserObject.Clear 更改为 ClearUserObjects(FUserObjects); 并添加了本地功能

  procedure ClearUserObjects(const AUserObjects: TObjectList<TObject>); {Framework}
  var
    i: Integer;
  begin
    FUserObjects.OwnsObjects := False;
    for i := FUserObjects.Count - 1 downto 0 do
      if FUserObjects.Items[i] is TReferencedObject then
      begin
        TReferencedObject(FUserObjects.Items[i]).RemoveReference;
        FUserObjects.Delete(i);
      end;
    FUserObjects.OwnsObjects := True;
    FUserObjects.Clear;
  end;