1

datasnap サーバーでオブジェクト参照を処理するには?

TUser オブジェクトを返す Datasnap サーバー メソッドがあります。

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 を呼び出したいと考えています。

4

1 に答える 1

1

DataSnapファイルData.DBXJSONReflect.pasとDatasnap.DSReflect.pasをプロジェクトディレクトリにコピーし、プロジェクトに追加して、3つの変更を加えました。

正しいReferenceCountを設定するためのData.DBXJSONReflectの2つの変更

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つの変更

1)TDsMethodValues.ClearReferenceParameters

FUserObject.ClearClearUserObjects(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;
于 2012-05-21T12:35:51.593 に答える