Ist die Implementierung der Delphi-Schnittstellenreferenz zukunftssicher?

8

Ich habe eine Hilfsklasse, die in der gesamten Anwendung weit verbreitet ist. Die Implementierung beruht auf der Zählung der Schnittstellenreferenz, die Idee ist ungefähr:

%Vor%

Die Implementierung beruht also darauf, dass IMyHelper am Ende der Methode den Gültigkeitsbereich verlässt, jedoch nicht vorher.

Was ist also gefragt, kann ich sicher sein, dass der Delphi-Compiler in Zukunft nicht mehr intelligent spielt und die Schnittstelle direkt nach der Erstellung freigibt, wenn die Variable im Rest der Methode nicht aufgerufen wird?

    
Daniel Maurić 01.02.2012, 09:28
quelle

2 Antworten

10

IMHO können Sie davon überzeugt sein. Das Out-of-Scope-Muster wird wahrscheinlich für den Anweisungsblock dieser Methode global bleiben. Dies wäre eine brechende Veränderung.

Siehe diesen Kommentar von Barry Kelly (von Embarcadero):

  

Zu Ihrem früheren Kommentar zu expliziten Variablen: Im hypothetischen (und brechenden) Fall, in dem wir die Verwendung der Schnittstellenvariablen optimiert haben, würden wir wahrscheinlich nicht nur die beschriebene RAII-ähnliche Funktionalität, sondern auch die explizite Variablenmethode durchbrechen; Die Werte, die FooNotifier und BarNotifier zugewiesen sind, werden nicht verwendet, daher können sie "theoretisch" früher freigegeben werden und möglicherweise sogar denselben Speicher wiederverwenden.

     

Aber natürlich kann die Zerstörung der Schnittstelle Nebenwirkungen haben, und darauf wird für den Effekt in der Post Verlass sein. Die Änderung der Sprache, so dass Nebenwirkungen wie diese sichtbare Veränderungen haben, tun wir nicht gerne.

Sie können also davon ausgehen, dass Embarcadero hier keine Änderungen der Abwärtskompatibilität einführt. Der Vorteil der Wiederverwendung eines Schnittstellenspeichers ist es nicht wert, die Kompatibilität zu brechen und Nebeneffekte einzuführen: Das Speichern eines Zeigers (4 oder 8 Bytes) ist heutzutage nicht wert, besonders wenn der Stapel bereits zugewiesen und ausgerichtet ist (x64-Modell verwendet) mehr Stapel als x86).

Nur wenn ein Garbage Collector in die Sprache eingeführt wird (was ich aus meiner persönlichen Sicht nicht möchte), kann sich die Lebensdauer der Objekte ändern. Aber in diesem Fall kann die Lebenszeit wahrscheinlich länger sein.

In allen Fällen können Sie Ihren eigenen Code erstellen, um sicherzustellen, dass er am Ende der Methode freigegeben wird:

%Vor%

Tatsächlich ist dies der Code, der bereits vom Compiler generiert wurde. Das zu schreiben wird vollkommen redundant sein, aber es wird sicherstellen, dass der Compiler dich nicht betrügt.

Wenn Sie von Schnittstellen und Referenzzählung sprechen, berücksichtigen Sie bitte das mögliche Problem von Zirkelverweisen in Delphi. Siehe diesen großartigen Artikel (dh "Beispiel 2-15") über die Notwendigkeit von "schwachen Zeigern" "für Zirkelreferenzen von Interfaces.

Andere Sprachen (wie Java oder C #) verwenden einen Garbage Collector, um dies zu beheben. Objective C verwendet einen expliziten Mechanismus zum Auflösen von schwachen Zeigern, um es zu lösen - siehe diese Diskussion oder diese Antwort auf eine mögliche Implementierung . Vielleicht wird eine zukünftige Version von Delphi eine ähnliche Implementierung wie das in Objective C eingeführte ARC-Modell in Betracht ziehen. Aber ich vermute, dass es eine explizite Syntax geben wird, um die Kompatibilität mit existierendem Code zu erhalten.

    
Arnaud Bouchez 01.02.2012, 09:50
quelle
4

Die Dokumentation sagt dies (Hervorhebung von mir):

  

Auf der Win32-Plattform werden Schnittstellenreferenzen normalerweise durch Referenzzählung verwaltet, die von den Methoden _AddRef und _Release abhängt, die von System / IInterface geerbt wurden. Wenn ein Objekt nur über Schnittstellen referenziert wird, ist es bei Verwendung der Standardimplementierung der Referenzzählung nicht erforderlich, es manuell zu zerstören. Das Objekt wird automatisch zerstört, wenn der letzte Verweis darauf außerhalb des Bereichs liegt.

Der Gültigkeitsbereich einer lokalen Variablen ist die Methode und daher lautet die aktuelle Spezifikation, dass _Release erst aufgerufen wird, wenn die Methode abgeschlossen ist.

Es gibt niemals ein Versprechen, dass die Spezifikationen in Zukunft nicht geändert werden, aber ich denke, dass die Wahrscheinlichkeit, dass an diesem Teil der Sprache etwas geändert wird, verschwindend gering ist.

    
David Heffernan 01.02.2012 09:54
quelle