Delphi: Since when are interface links no longer issued at the end of the c-block?

I recently came across a problem caused by some very old code that I wrote, which obviously assumed that the interface references used in the with statement would be released as soon as with -block remained - kind of like an implicit try-finally -block (similar to C # using -statement, if I understood correctly).

Apparently (in Delphi 2009) this is not (no more?) A case. Does anyone know when this happened? Or was my code just wrong for a start?

To clarify, here is a simplified example:

 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 

Whenever someone started the old argument with is evil, it was always one of the examples that I had in mind that made me go β€œYes, but ...”. I think I was wrong ... Can anyone confirm?

+4
source share
2 answers

The saved word with in Pascal / Delphi is used only for easy access to elements of records or objects / classes (i.e., not to mention the name of the record / object / class). It is very different from C # with , which relates to garbage collection. It exists in the language of Pascal from the birthday of records in order to simplify the code access to many data members (then they were simply called "fields").

To summarize, with has nothing to do with garbage collection, memory release, or destruction of object instances. Objects that were constructed in the with header can only be initialized in a separate line of code before that, the same thing.

+17
source

This WITH behavior has never changed. To achieve the expected behavior, you can change your code as follows:

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

or you can do it in the procedure:

 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; 
+3
source

All Articles