简体   繁体   English

当我尝试免费的 TJSONObject 时访问冲突

[英]Access violation when i try free TJSONObject

I have the code below, but when I try to free the variable checkID, I get an access violation error, and if I don't destroy it I will have a memory leak problem.我有下面的代码,但是当我尝试释放变量 checkID 时,出现访问冲突错误,如果我不销毁它,我将遇到 memory 泄漏问题。

function TdtmData.CheckID(AID: String): Boolean;
var
  checkID : TJSONObject;
  clientModule : TcmClientModule;
  ok : Boolean;
begin
  Result := False;
  try
    try
      clientModule := TcmClientModule.Create(Self);
      checkID := clientModule.smMethodsServerClient.CheckID(AID);
      ok := checkID.GetValue<Boolean>('Register', False);
      if not(ok) then
        raise Exception.Create('ID ERROR.');
    finally
      clientModule.DisposeOf;
      checkID.Free; // <-- The error is here (Access violation)
    end;
    Result := ok;
  except
    on e : Exception do
      raise Exception.Create(e.Message);
  end;

end;

The smMethodsServerClient.CheckID(AID) method was created automatically through the TDSRestConnection component. smMethodsServerClient.CheckID(AID) 方法是通过 TDSRestConnection 组件自动创建的。

function TsmMethodsServerClient.CheckID(AID: string; const ARequestFilter: string): TJSONObject;
begin
  if FCheckIDCommand = nil then
  begin
    FCheckIDCommand  := FConnection.CreateCommand;
    FCheckIDCommand.RequestType := 'GET';
    FCheckIDCommand.Text := 'TsmMethodsServer.CheckID';
    FCheckIDCommand.Prepare(TsmMethodsServer_CheckID);
  end;
  FCheckIDCommand.Parameters[0].Value.SetWideString(AIDPDV);
  FCheckIDCommand.Execute(ARequestFilter);
  Result := TJSONObject(FCheckIDCommand.Parameters[1].Value.GetJSONValue(FInstanceOwner));
end;

I also used the Datasnap REST Client Module wizard to create my class TcmClientModule.我还使用 Datasnap REST 客户端模块向导来创建我的 class TcmClientModule。

JSONValue used as a parameter of DataSnap does not need to be Free.用作 DataSnap 的参数的 JSONValue 不需要是 Free。

In addition, if you release the memory of the parameter object, an error may occur when you release the DataSnap DataModule or when you call the interface where the parameter was used for the second time.另外,如果释放参数object的memory,释放DataSnap DataModule或第二次调用该参数的接口时可能会出错。

Even if you create a new JSONValue parameter every time to use the DataSnap interface, there are no problems such as memory leaks.即使每次都创建一个新的 JSONValue 参数来使用 DataSnap 接口,也不会出现 memory 泄漏等问题。

Moreover, JSONValue objects received as a result of the DataSnap interface should not be freed further.此外,不应进一步释放作为 DataSnap 接口结果接收的 JSONValue 对象。

================================================= =================================================

clientModule.DisposeOf;

This frees memory for checkID.这为 checkID 释放了 memory。 However, there is no setting for "checkID:= nil".但是,“checkID:= nil”没有设置。 The conditional statement below will always be executed and an error occurs when executing.下面的条件语句会一直执行,执行时会出错。

if Assigned(checkId) then 
  checkID.Free;

Maybe when you are doing this thing也许当你在做这件事时

clientModule.DisposeOf;

checkID will be destroyed, because checkID is a part of clientModule due to this part of code checkID将被销毁,因为checkIDclientModule的一部分,因为这部分代码

clientModule.smMethodsServerClient.CheckID(AID);

You can try clear checkID first and then clear clientModule .您可以先尝试清除checkID ,然后再清除clientModule

Update: Another way to avoid error is checking checkId before destroying.更新:避免错误的另一种方法是在销毁之前检查checkId Maybe this way is suitable:也许这种方式是合适的:

if Assigned(checkId) then 
  checkID.Free;

Maybe besides this check you need check object for null too.也许除了这个检查之外,您还需要检查 object 的null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM