문제

나는 최근에 내가 쓴 아주 오래된 코드로 인한 문제를 우연히 발견했는데 with 진술은 즉시 공개됩니다 with- 블록은 왼쪽으로 - 암시 적과 같습니다 try-finally-블록 (C#과 유사합니다 using-내가 올바르게 이해 한 경우).

분명히 (Delphi 2009에서) 이것은 더 이상이 아닙니다. 이런 일이 언제 일어 났는지 아는 사람이 있습니까? 아니면 내 코드가 처음부터 잘못 되었습니까?

명확히하기 위해, 여기 단순화 된 예는 다음과 같습니다.

type
  IMyIntf = interface;
  TSomeObject = class(TInterfacedObject, IMyIntf)
  protected
    constructor Create; override; // creates some sort of context
    destructor Destroy; override; // cleans up the context created in Create
  public
    class function GetMyIntf: IMyIntf; //a factory method, calling the constructor
  end;

procedure TestIt;
begin
  DoSomething;
  with (TSomeObject.GetMyIntf) do
    begin
      DoStuff;
      DoMoreStuff;
    end; // <- expected: TSomeObject gets destroyed because its ref.count is decreased to 0
  DoSomethingElse;
end; // <- this is where TSomeObject.Destroy actually gets called

누군가가 늙음을 시작할 때마다 "with 악한 "논쟁은 항상 내가 명심했던 한 가지 예 였는데,"예, 그러나 ... ". 내가 틀린 것 같다 ... 누군가를 확인할 수 있습니까?

도움이 되었습니까?

해결책

그만큼 with Pascal/Delphi의 보존 된 단어는 레코드 또는 객체/클래스의 구성원에게 쉽게 액세스하는 데만 사용됩니다 (즉, 레코드/오브젝트/클래스 이름을 언급하지 않기 위해). C#과는 매우 다릅니다. with 그것은 쓰레기 수집과 관련이 있습니다. 그것은 당일부터 파스칼 언어로 존재했습니다. records 많은 데이터 멤버들에게 코드 호출을 단순화하기 위해 태어났습니다 (뒤로 "필드"라고 불).

요약, with 쓰레기 수집, 메모리 출시 또는 객체 인스턴스 파괴와 관련이 없습니다. The에서 구성된 객체 with 헤더는 이전에 별도의 코드 라인으로 초기화되었을 수 있습니다. 동일합니다.

다른 팁

이것은 행동이 바뀌지 않았습니다. 예상되는 동작에 도달하려면 이러한 방식으로 코드를 변경할 수 있습니다.

    procedure TestIt;
    var
       myIntf: IMyIntf; 
    begin
      DoSomething;

      myIntf := TSomeObject.GetMyIntf
      DoStuff;
      DoMoreStuff;
      myIntf := nil; // <- here is where TSomeObject.Destroy called

      DoSomethingElse;
    end; 

또는 절차에서 할 수 있습니다.

procedure TestIt;

   procedure DoAllStuff;
   var
      myIntf: IMyIntf; 
   begin
      myIntf := TSomeObject.GetMyIntf
      DoStuff;
      DoMoreStuff;
   end;  // <- here is where TSomeObject.Destroy called

begin    
  DoSomething;
  DoAllStuff;
  DoSomethingElse;
end; 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top