Zitat von
Robert:
Wäre eine Überarbeitung der Interfaces in Delphi32 langsam mal angebracht
Das werden wir in der kommenden Version von Delphi für
Win32 wohl nicht erleben, Änderungen mithilfe eines GC zögen weitreichende Folgen mit sich.
Es könnte jedoch sein, dass sich der Compiler für den Spezialfall der Schleife auf eine Art "GetInterfaceWithoutAffectingRefCount" Nachricht des Objekts beruft, um Methodenzeiger auf die die durch das Interface zu implementierenden Methoden zu bekommen. Technisch möglich wäre dieser Ansatz sogar bei Interfaces, die als Containerausdruck übergeben worden wären.
Doch, selbst wenn die For..In-Schleife keine Referenzzählung durchführen würde, könnte Code der Art
Delphi-Quellcode:
var
MyObj: TImplementsIEnumerable;
MyIntf: IEnumerable;
S: string
begin
MyObj := TImplementsIEnumerable.Create;
try
//..
for S in MyObj do // references MyObj -> has to be initiated
begin
MyIntf := MyObj; // calls _AddRef -> "RefCount" = 1
MyIntf := nil; //calls _Release -> "RefCount" = 0 -> .Destroy
end;
finally
FreeAndNil(MyObj);
end;
end;
Sollte im obigen Beispiel
MyObj mehr als ein Element besitzen, könnte die Zeile mit dem For-Ausdruck zu Problemen führen, selbst, wenn hier ohne Referenzzähler gearbeitet wird, spätestens aber der Aufruf von
FreeAndNil, denn die Zuweisung von
nil auf
MyIntf hätte das Objekt bereits zerstört!
Für diesen Spezialfall könnte man dem Compiler vielleicht noch eine besondere Prüfung zumuten, so dass For-Schleifen bei einer internen Verwendung doch
mit einer Referenzzählung arbeiten.
FreeAndNil wie oben aber auch Aufruf von anderen Methoden, die ihrerseits den Referenzzähler verwenden, sind dann wohl aber nur noch unter größtem Aufwand zur Übersetzungszeit als Fehlerquellen erkennbar...
Die angeführten Beispiele zeigen zusammen mit der Idee der Referenz auf Methoden ohne Referenzzählung die von den Delphi-Entwicklern bereits oft als Antwort geltende Idee "Entweder Interfaces oder Objektreferenzen" als denkbare Lösung.