DELPHI : 언제부터 인터페이스 참조가 더 이상 블록이 끝나지 않습니까?
-
22-07-2019 - |
문제
나는 최근에 내가 쓴 아주 오래된 코드로 인한 문제를 우연히 발견했는데 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;