Compiler-Attribute

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Attribute (RTTI)


Einige spezielle Attribute lösen bestimmte Features von Delphi-Compilern aus.

Ref

Mit dem Attribut Ref werden konstante Funktionsparameter qualifiziert, sodass sie per Referenz (nicht per Wert) an die Funktion übergeben werden. Weitere Informationen finden Sie unter Konstantenparameter.

Volatile

Mit dem Attribut volatile werden Felder gekennzeichnet, die von verschiedenen Threads verändert werden, damit die Codeerzeugung keine Optimierung durch Kopieren des Wertes in ein Register oder an eine andere temporäre Speicherposition durchführt.

Mit dem Attribut volatile können Sie die folgenden Deklarationen kennzeichnen:

Mit dem Attribut volatile können Sie die folgenden Deklarationen nicht kennzeichnen:

type
    TMyClass = class
    private
        [volatile] FMyVariable: TMyType;
    end;

Attribute weak und unsafe

Hinweis: Die Verwendung von schwachen (weak) und unsicheren (unsafe) Referenzen wurde ursprünglich im Rahmen der Unterstützung der ARC-Speicherverwaltung für mobile Plattformen eingeführt. Da ARC nun ausgelaufen ist, steht dieses Feature nur noch für Interface-Referenzen zur Verfügung.

Weak

Weak ist eine Interface-Referenz, die den Referenzzähler des Objekts, auf das verwiesen wird, nicht erhöht. Sie wird mit dem Modifizierer [weak] gekennzeichnet. Dieses Feature wird nur von Delphi unterstützt. Sie können weak-Referenzen in folgenden Fällen verwenden:

  • Um zu vermeiden, dass der Referenzzähler erhöht wird.
  • Um Interface-Referenzen zu verwalten. Das heißt, dass das System sie nachverfolgt, wenn das eigentliche Objekt gelöscht wird.
Hinweis: Da weak-Referenzen vollständig verwaltet sind, werden sie automatisch auf nil gesetzt, wenn das referenzierte Objekt freigegeben wird.
  • Um zirkuläre Referenzen zwischen zwei Objekten mit Querreferenzen aufzuheben. In diesem Fall entsteht ein Speicherleck.

Betrachten Sie als Beispiel das folgende Interface, das eine Referenz auf ein anderes Interface desselben Typs akzeptiert, und eine Klasse, die es mit einer internen Referenz implementiert:

type
  ISimpleInterface = interface 
  procedure DoSomething; 
  procedure AddObjectRef(Simple: ISimpleInterface); 
 end; 
 TObjectOne = class(TInterfacedObject, ISimpleInterface)
 private 
  AnotherObj: ISimpleInterface; 
 public 
  procedure DoSomething; 
  procedure AddObjectRef(Simple: ISimpleInterface); 
 end;

Wenn Sie zwei Objekte erstellen und wechselseitig auf diese verweisen, entsteht ein Speicherleck:

var 
 One, Two: ISimpleInterface; 
begin 
  One := TObjectOne.Create; 
  Two := TObjectOne.Create;
  One.AddObjectRef(Two); 
  Two.AddObjectRef(One);

Die jetzt in Delphi verfügbare Lösung ist, das private Feld AnotherObj als eine weak-Interface-Referenz zu kennzeichnen:

private 
  [weak] AnotherObj: ISimpleInterface;

Bei dieser Änderung wird der Referenzzähler nicht verändert, wenn Sie das Objekt als Parameter an den AddObjectRef-Aufruf übergeben. Er bleibt bei 1 und fällt zurück auf 0, wenn die Variablen den Gültigkeitsbereich verlassen, und die Objekte werden aus dem Speicher freigegeben.

Hinweis: Sie können eine [weak]-Variable nur an einen als [weak] gekennzeichneten var- oder out-Parameter übergeben. Sie können keine reguläre starke Referenz an einen [weak]-var- oder -out-Parameter übergeben.

Unsafe

Eine unsafe-Referenz ist eine Interface-Referenz, die den Referenzzähler des Objekts, auf das verwiesen wird, nicht erhöht. Sie wird mit dem Modifizierer [unsafe] gekennzeichnet.

Hinweis: Unsafe-Referenzen werden nicht verwaltet, ähnlich wie ein Zeiger ohne zusätzliche Compiler-Unterstützung.

Sie können unsafe verwenden, wenn Sie eine Interface-Referenz erstellen möchten, die nicht in die Gesamtzahl der Referenzen einbezogen wird. Zum Beispiel:

procedure TForm3.Button2Click(Sender: TObject); 
var 
 [unsafe] OneIntf: ISimpleInterface;
begin 
 OneIntf := TObjectOne.Create; 
 OneIntf.DoSomething; 
end;
Hinweis: Sie können eine [Unsafe]-Variable nur an einen var- oder out-Parameter übergeben, der ebenfalls als [Unsafe] gekennzeichnet ist. Sie können keine reguläre starke Referenz an [Unsafe] var oder -out übergeben.

Siehe auch