<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alejandra.Barrientos</id>
	<title>RAD Studio - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alejandra.Barrientos"/>
	<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/de/Spezial:Beitr%C3%A4ge/Alejandra.Barrientos"/>
	<updated>2026-08-30T21:52:59Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Programmieren_von_Reaktionen_auf_Benutzeraktionen_im_Quelltext-Editor_(IDE-Tutorial)&amp;diff=215162</id>
		<title>Programmieren von Reaktionen auf Benutzeraktionen im Quelltext-Editor (IDE-Tutorial)</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Programmieren_von_Reaktionen_auf_Benutzeraktionen_im_Quelltext-Editor_(IDE-Tutorial)&amp;diff=215162"/>
		<updated>2021-10-08T21:15:50Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: RS-108915 Updated Screenshots&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Ihre erste Anwendung mit {{Variables|Product}} - Index (IDE-Tutorial)}}&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Anleitungen in diesem Abschnitt gestalten Sie Ihre Anwendung interaktiv und fügen die gewünschte Funktionalität hinzu. In diesem Abschnitt werden die Ereignisbehandlungsroutinen programmiert, d.&amp;amp;nbsp;h. die Reaktionen auf die Auswahl der verschiedenen Einträge im Hauptmenü und auf andere Arten von Benutzerinteraktionen.&lt;br /&gt;
&lt;br /&gt;
==Beginnen der Programmierung==&lt;br /&gt;
&lt;br /&gt;
Fangen Sie mit der Definition einer &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;-Variable an, die während der Ausführung der Anwendung den Namen der aktuell geöffneten Textdatei aufnimmt. &lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wählen Sie in {{Delphi}} in der Statusleiste das Register &#039;&#039;&#039;Code&#039;&#039;&#039;, um den &#039;&#039;&#039;[[Quelltext-Editor|Quelltext-Editor]]&#039;&#039;&#039; zu öffnen. Verwenden Sie den  &#039;&#039;&#039;Quelltext-Editor&#039;&#039;&#039;, um im Abschnitt &amp;quot;private&amp;quot; der Klasse &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; eine &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;-Variable namens &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; und zwar im &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;interface&amp;lt;/source&amp;gt;-Teil zu definieren:&lt;br /&gt;
&lt;br /&gt;
: [[Image:Code_Editor-CurrentFile_Delphi.jpg|Link=|Code Editor for Delphi]]&lt;br /&gt;
: &#039;&#039;Definieren der &amp;quot;private&amp;quot; Variable &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; ({{Delphi}}-Ansicht)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wählen Sie in {{CBuilder}} in der Statusleiste das Register &#039;&#039;&#039;TextEditorUnit.h&#039;&#039;&#039;, um die Header-Datei der Unit im  &#039;&#039;&#039;[[Quelltext-Editor|Quelltext-Editor]]&#039;&#039;&#039; zu öffnen. Verwenden Sie &#039;&#039;&#039;Quelltext-Editor&#039;&#039;&#039;, um eine &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;-Variable namens &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; im &amp;lt;source lang=&amp;quot;cpp&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;private&amp;lt;/source&amp;gt; Abschnitt von &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; zu deklarieren:&lt;br /&gt;
&lt;br /&gt;
: [[Image:Code_Editor-CurrentFile_C++.jpg|Link=|Code Editor for C++]]&lt;br /&gt;
: &#039;&#039;Definieren der &amp;quot;private&amp;quot; Variable CurrentFile ({{CBuilder}}-Ansicht)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um zwischen dem &#039;&#039;&#039;[[Formular-Designer|Formular-Designer]]&#039;&#039;&#039; und dem &#039;&#039;&#039;[[Quelltext-Editor|Quelltext-Editor]]&#039;&#039;&#039; zu wechseln, drücken Sie die Taste &amp;lt;code&amp;gt;F12&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Aktualisieren der Statusleiste als Reaktion auf Aktionen im Texteditor==&lt;br /&gt;
&lt;br /&gt;
Wenn der Benutzer den &#039;&#039;Textcursor&#039;&#039; bewegt oder den Inhalt der &#039;&#039;&#039;[[lib_de:FMX.Memo.TMemo|TMemo]]&#039;&#039;&#039;-Komponente ändert, müssen Sie die Statusleiste aktualisieren. Da die Statusleiste als Reaktion auf viele verschiedene Ereignisse aktualisiert werden muss, können Sie eine einzige Prozedur im Code definieren und diese Prozedur dann später von jeder Ereignisbehandlungsroutine aus aufrufen, die die Statusleiste aktualisieren muss.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fügen Sie in {{Delphi}} zum Definieren dieser neuen Prozedur in Ihrer Anwendung die folgende Prozedursignatur dem &amp;quot;private&amp;quot; Abschnitt der Klasse &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; hinzu und zwar im &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;interface&amp;lt;/source&amp;gt;-Teil direkt unterhalb der Variable &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt;, die Sie zuvor definiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure UpdateStatusBar;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Klicken Sie in Ihrem Code mit der rechten Maustaste auf &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt;, und wählen Sie &#039;&#039;&#039;Klasse beim Cursor vervollständigen&#039;&#039;&#039;, damit {{Product}} ein Grundgerüst für die Definition der Prozedur hinzufügt und zwar im &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;implementation&amp;lt;/source&amp;gt;-Teil des Codes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.UpdateStatusBar;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definieren Sie die Logik der Prozedur &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; zwischen den Schlüsselwörtern &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;begin&amp;lt;/source&amp;gt; und &amp;lt;source lang=&amp;quot;delphi&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;end&amp;lt;/source&amp;gt; wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
LineNumber.Text := &#039;L: &#039; + (Editor.CaretPosition.Line+1).ToString;&lt;br /&gt;
ColumnNumber.Text := &#039;C: &#039; + (Editor.CaretPosition.Pos+1).ToString;&lt;br /&gt;
LineCount.Text := &#039;Lines: &#039; + Editor.Lines.Count.ToString;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fügen Sie in C++ zum Definieren dieser neuen Funktion in Ihrer Anwendung die folgende Funktionssignatur dem &amp;lt;source lang=&amp;quot;cpp&amp;quot; enclose=&amp;quot;none&amp;quot;&amp;gt;private&amp;lt;/source&amp;gt; Abschnitt der Klasse &#039;&#039;&#039;TTextEditorForm&#039;&#039;&#039; in der Datei &#039;&#039;TextEditorUnit.h&#039;&#039; direkt unterhalb der Variable &amp;lt;code&amp;gt;CurrentFile&amp;lt;/code&amp;gt; hinzu, die Sie zuvor definiert haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void UpdateStatusBar();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wählen Sie die Implementierungsdatei &#039;&#039;TextEditorUnit.cpp&#039;&#039; aus, und implementieren Sie diese Funktion wie folgt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void TTextEditorForm::UpdateStatusBar()&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;LineNumber-&amp;gt;Text = L&amp;quot;L: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition.Line+1);&lt;br /&gt;
    TextEditorForm-&amp;gt;ColumnNumber-&amp;gt;Text = L&amp;quot;C: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition.Pos+1);&lt;br /&gt;
    TextEditorForm-&amp;gt;LineCount-&amp;gt;Text = L&amp;quot;Lines: &amp;quot; + String(TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Count);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sie können jetzt &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; aus allen Ereignisbehandlungsroutinen aufrufen, um die Statusleiste zu aktualisieren.&lt;br /&gt;
&lt;br /&gt;
Das erste Mal sollten Sie die in der Statusleiste angezeigten Informationen beim Start Ihrer Anwendung aktualisieren. Dafür können Sie das Ereignis &#039;&#039;&#039;OnCreate&#039;&#039;&#039; des Formulars verwenden:&lt;br /&gt;
&lt;br /&gt;
# Klicken Sie auf die Registerkarte &#039;&#039;&#039;Design&#039;&#039;&#039;, um zurück zum [[Formular-Designer|Formular-Designer]] zu wechseln.&lt;br /&gt;
# Wählen Sie in der [[Strukturansicht|Strukturansicht]] die Formular-Komponente mit dem Namen &amp;lt;code&amp;gt;TextEditorForm&amp;lt;/code&amp;gt; aus.&lt;br /&gt;
# Klicken Sie im [[Objektinspektor|Objektinspektor]] auf die Registerkarte &#039;&#039;&#039;Ereignisse&#039;&#039;&#039;.&lt;br /&gt;
# Doppelklicken Sie auf der Registerkarte &#039;&#039;&#039;Ereignisse&#039;&#039;&#039; auf das Wertefeld des &#039;&#039;&#039;OnCreate&#039;&#039;&#039;-Ereignisses. {{Product}} wechselt zum [[Quelltext-Editor|Quelltext-Editor]] und fügt ein Grundgerüst für die Definition der neuen Ereignisbehandlungsroutine hinzu. Rufen Sie mit dieser Ereignisbehandlungsroutine Ihre &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt;-Prozedur auf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.FormCreate(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.Lines.Add(&#039;&#039;);&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::FormCreate(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Add(L&amp;quot;&amp;quot;);&lt;br /&gt;
        UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beachten Sie, dass vor dem Aufruf von &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; eine leere Zeile in der TMemo-Komponente eingefügt wird. Dadurch wird der Zeilenzähler des Memofeldes initialisiert, damit der Zeilenzähler in der Statusleiste am Anfang &amp;quot;1&amp;quot; Zeile anstatt &amp;quot;0&amp;quot; Zeilen anzeigt.&lt;br /&gt;
&lt;br /&gt;
Wiederholen Sie die obigen Schritte für die Ereignisse &#039;&#039;&#039;OnKeyUp&#039;&#039;&#039; und &#039;&#039;&#039;OnMouseUp&#039;&#039;&#039; der TMemo-Komponente &amp;lt;code&amp;gt;Editor&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.EditorKeyUp(Sender: TObject; var Key: Word;&lt;br /&gt;
  var KeyChar: Char; Shift: TShiftState);&lt;br /&gt;
begin&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TTextEditorForm.EditorMouseUp(Sender: TObject; Button: TMouseButton;&lt;br /&gt;
  Shift: TShiftState; X, Y: Single);&lt;br /&gt;
begin&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::EditorKeyUp(TObject *Sender, WORD &amp;amp;Key, System::WideChar &amp;amp;KeyChar,&lt;br /&gt;
          TShiftState Shift)&lt;br /&gt;
{&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void __fastcall TTextEditorForm::EditorMouseUp(TObject *Sender, TMouseButton Button,&lt;br /&gt;
          TShiftState Shift, float X, float Y)&lt;br /&gt;
{&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Erstellen von Ereignisbehandlungsroutinen für die Einträge im Menü &amp;quot;File&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Wiederholen Sie die obigen Schritte für die Ereignisse &#039;&#039;&#039;OnKeyUp&#039;&#039;&#039; und &#039;&#039;&#039;OnMouseUp&#039;&#039;&#039; der TMemo-Komponente (&amp;lt;code&amp;gt;Editor&amp;lt;/code&amp;gt;):&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:[[Image:Code_Editor-IDETutorialSelectingNewAction.jpg|Link=|Selecting New Action]]&lt;br /&gt;
&lt;br /&gt;
Wählen Sie dann im &#039;&#039;&#039;Objektinspektor&#039;&#039;&#039; die Registerkarte &#039;&#039;&#039;Ereignisse&#039;&#039;&#039; aus, und doppelklicken Sie auf das Eingabefeld neben dem Ereignis &amp;lt;code&amp;gt;OnExecute&amp;lt;/code&amp;gt;. Der &#039;&#039;&#039;Quelltext-Editor&#039;&#039;&#039; wird geöffnet, und ein Grundgerüst für die neue Ereignisbehandlungsroutine wird angezeigt. Schreiben Sie in diese Ereignisbehandlungsroutine den Code, der ausgeführt werden soll, wenn der Benutzer {{Menu|Datei &amp;amp;gt; Neu}}.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TTextEditorForm.NewActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  UserResponse: Integer;&lt;br /&gt;
begin&lt;br /&gt;
  // Ask for confirmation if the memo is not empty.&lt;br /&gt;
  if not Editor.Text.IsEmpty then&lt;br /&gt;
  begin&lt;br /&gt;
    UserResponse := TDialogServiceSync.MessageDialog(&lt;br /&gt;
      &#039;This will clear the current document. Do you want to continue?&#039;,&lt;br /&gt;
      TMsgDlgType.mtInformation, mbYesNo, TMsgDlgBtn.mbYes, 0);&lt;br /&gt;
    if UserResponse = mrYes then&lt;br /&gt;
    begin&lt;br /&gt;
      Editor.Text := &#039;&#039;;&lt;br /&gt;
      Editor.Lines.Add(&#039;&#039;); // Initialize the memo line count to &amp;quot;1&amp;quot;.&lt;br /&gt;
      UpdateStatusBar;&lt;br /&gt;
      CurrentFile := &#039;&#039;; // New files have no file name until saved.&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TTextEditorForm::NewActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (!TextEditorForm-&amp;gt;Editor-&amp;gt;Text.IsEmpty()) {&lt;br /&gt;
        int UserResponse = TDialogServiceSync::MessageDialog(&lt;br /&gt;
            L&amp;quot;This will clear the current document. Do you want to continue?&amp;quot;,&lt;br /&gt;
            TMsgDlgType::mtInformation, mbYesNo, TMsgDlgBtn::mbYes, 0);&lt;br /&gt;
        if (UserResponse == mrYes) {&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Text = L&amp;quot;&amp;quot;;&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;Add(L&amp;quot;&amp;quot;);  // Initialize the memo line count to &amp;quot;1&amp;quot;.&lt;br /&gt;
            UpdateStatusBar();&lt;br /&gt;
            CurrentFile = L&amp;quot;&amp;quot;;  // New files have no file name until saved.&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
// File &amp;gt; Open&lt;br /&gt;
procedure TTextEditorForm.OpenActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  FileName: String;&lt;br /&gt;
begin&lt;br /&gt;
  if OpenFileDialog.Execute = True then&lt;br /&gt;
  begin&lt;br /&gt;
    FileName := OpenFileDialog.FileName;&lt;br /&gt;
    if FileExists(FileName) then&lt;br /&gt;
    begin&lt;br /&gt;
      Editor.Lines.LoadFromFile(FileName);&lt;br /&gt;
      CurrentFile := FileName;&lt;br /&gt;
      Caption := &#039;Text Editor - &#039; + ExtractFileName(FileName);&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save&lt;br /&gt;
procedure TTextEditorForm.SaveActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  if CurrentFile = &#039;&#039; then&lt;br /&gt;
    SaveAsAction.Execute()&lt;br /&gt;
  else&lt;br /&gt;
    Editor.Lines.SaveToFile(CurrentFile);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save As&lt;br /&gt;
procedure TTextEditorForm.SaveAsActionExecute(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  FileName: String;&lt;br /&gt;
  UserResponse: TModalResult;&lt;br /&gt;
begin&lt;br /&gt;
  if SaveFileDialog.Execute = True then&lt;br /&gt;
  begin&lt;br /&gt;
    FileName := SaveFileDialog.FileName;&lt;br /&gt;
    if FileExists(FileName) then&lt;br /&gt;
    begin&lt;br /&gt;
      UserResponse := TDialogServiceSync.MessageDialog(&lt;br /&gt;
        &#039;File already exists. Do you want to overwrite?&#039;,&lt;br /&gt;
        TMsgDlgType.mtInformation, mbYesNo, TMsgDlgBtn.mbYes, 0);&lt;br /&gt;
      if UserResponse = mrNo then&lt;br /&gt;
        Exit;&lt;br /&gt;
    end;&lt;br /&gt;
    Editor.Lines.SaveToFile(FileName);&lt;br /&gt;
    CurrentFile := FileName;&lt;br /&gt;
    Caption := &#039;Text Editor - &#039; + ExtractFileName(FileName);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Exit&lt;br /&gt;
procedure TTextEditorForm.ExitActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Application.Terminate;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// File &amp;gt; Open&lt;br /&gt;
void __fastcall TTextEditorForm::OpenActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;OpenFileDialog-&amp;gt;Execute()) {&lt;br /&gt;
        String FileName = TextEditorForm-&amp;gt;OpenFileDialog-&amp;gt;FileName;&lt;br /&gt;
        if (FileExists(FileName)) {&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;LoadFromFile(FileName);&lt;br /&gt;
            CurrentFile = FileName;&lt;br /&gt;
            Caption = L&amp;quot;Text Editor - &amp;quot; + ExtractFileName(FileName);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save&lt;br /&gt;
void __fastcall TTextEditorForm::SaveActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentFile == L&amp;quot;&amp;quot;) {&lt;br /&gt;
        TextEditorForm-&amp;gt;SaveAsAction-&amp;gt;Execute();&lt;br /&gt;
    } else {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;SaveToFile(CurrentFile);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Save As&lt;br /&gt;
void __fastcall TTextEditorForm::SaveAsActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;SaveFileDialog-&amp;gt;Execute()) {&lt;br /&gt;
        String FileName = TextEditorForm-&amp;gt;SaveFileDialog-&amp;gt;FileName;&lt;br /&gt;
        if (FileExists(FileName)) {&lt;br /&gt;
            String UserResponse = TDialogServiceSync::MessageDialog(&lt;br /&gt;
                L&amp;quot;File already exists. Do you want to overwrite?&amp;quot;,&lt;br /&gt;
                TMsgDlgType::mtInformation, mbYesNo, TMsgDlgBtn::mbYes, 0);&lt;br /&gt;
            if (UserResponse == System::Uitypes::TMsgDlgBtn::mbNo) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;Lines-&amp;gt;SaveToFile(FileName);&lt;br /&gt;
        CurrentFile = FileName;&lt;br /&gt;
        Caption = L&amp;quot;Text Editor - &amp;quot; + ExtractFileName(FileName);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// File &amp;gt; Exit&lt;br /&gt;
void __fastcall TTextEditorForm::ExitActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    Application-&amp;gt;Terminate();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Erstellen von Ereignisbehandlungsroutinen für die Einträge im Menü &amp;quot;Edit&amp;quot; und &amp;quot;Format&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Gehen Sie für die Implementierung der Aktionen für die Einträge in den Menüs &amp;quot;Edit&amp;quot; und &amp;quot;Format&amp;quot; genauso vor wie bei den Aktionen für das Menü &amp;quot;File&amp;quot; vor. Diese Ereignisbehandlungsroutinen sind ziemlich einfach: sie leiten die Aktion nur an das Memofeld weiter, weil die gesamte benötigte Funktionalität bereits in der Klasse [[lib_de:FMX.Memo.TMemo|TMemo]] implementiert ist, und sie rufen &amp;lt;code&amp;gt;UpdateStatusBar&amp;lt;/code&amp;gt; auf, falls die Aktion Auswirkungen auf die Position des Textcursors oder den Zeilenzähler hat.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
// Edit &amp;gt; Cut&lt;br /&gt;
procedure TTextEditorForm.CutActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.CutToClipboard;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Copy&lt;br /&gt;
procedure TTextEditorForm.CopyActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.CopyToClipboard;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Paste&lt;br /&gt;
procedure TTextEditorForm.PasteActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.PasteFromClipboard;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Select All&lt;br /&gt;
procedure TTextEditorForm.SelectAllActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.SelectAll;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Undo&lt;br /&gt;
procedure TTextEditorForm.UndoActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.UnDo;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Delete&lt;br /&gt;
procedure TTextEditorForm.DeleteActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  if Editor.SelLength &amp;gt; 0 then&lt;br /&gt;
    Editor.DeleteSelection&lt;br /&gt;
  else&lt;br /&gt;
    Editor.DeleteFrom(Editor.CaretPosition, 1, [TDeleteOption.MoveCaret]);&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Format &amp;gt; Word Wrap&lt;br /&gt;
procedure TTextEditorForm.WordWrapActionExecute(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
  Editor.WordWrap := not Editor.WordWrap;&lt;br /&gt;
  WordWrapAction.Checked := Editor.WordWrap;&lt;br /&gt;
  UpdateStatusBar;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Edit &amp;gt; Cut&lt;br /&gt;
void __fastcall TTextEditorForm::CutActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;CutToClipboard();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Copy&lt;br /&gt;
void __fastcall TTextEditorForm::CopyActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;CopyToClipboard();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Paste&lt;br /&gt;
void __fastcall TTextEditorForm::PasteActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;PasteFromClipboard();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Select All&lt;br /&gt;
void __fastcall TTextEditorForm::SelectAllActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;SelectAll();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Undo&lt;br /&gt;
void __fastcall TTextEditorForm::UndoActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;UnDo();&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Edit &amp;gt; Delete&lt;br /&gt;
void __fastcall TTextEditorForm::DeleteActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    if (TextEditorForm-&amp;gt;Editor-&amp;gt;SelLength &amp;gt; 0) {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;DeleteSelection();&lt;br /&gt;
    } else {&lt;br /&gt;
        TextEditorForm-&amp;gt;Editor-&amp;gt;DeleteFrom(&lt;br /&gt;
            TextEditorForm-&amp;gt;Editor-&amp;gt;CaretPosition, 1,&lt;br /&gt;
            Fmx::Memo::TDeleteOptions() &amp;lt;&amp;lt; Fmx::Memo::TDeleteOption::MoveCaret);&lt;br /&gt;
    }&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Format &amp;gt; Word Wrap&lt;br /&gt;
void __fastcall TTextEditorForm::WordWrapActionExecute(TObject *Sender)&lt;br /&gt;
{&lt;br /&gt;
    TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap = !TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap;&lt;br /&gt;
    TextEditorForm-&amp;gt;WordWrapAction-&amp;gt;Checked = TextEditorForm-&amp;gt;Editor-&amp;gt;WordWrap;&lt;br /&gt;
    UpdateStatusBar();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weiter==&lt;br /&gt;
&lt;br /&gt;
[[Compilieren und Ausführen der Anwendung (IDE-Tutorial)|Compilieren und Ausführen der Anwendung]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:C++]]&lt;br /&gt;
[[Category:XE6]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Coding responses to user actions in the Code Editor (IDE Tutorial)]]&lt;br /&gt;
[[fr:Codage des réponses aux actions des utilisateurs dans l&#039;éditeur de code (tutoriel de l&#039;EDI)]]&lt;br /&gt;
[[ja:ユーザー アクションに対する応答をコード エディタでコーディングする（IDE チュートリアル）]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-IDETutorialSelectingNewAction.jpg&amp;diff=215161</id>
		<title>Datei:Code Editor-IDETutorialSelectingNewAction.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-IDETutorialSelectingNewAction.jpg&amp;diff=215161"/>
		<updated>2021-10-08T21:15:15Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: Datei hochgeladen mit MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Datei hochgeladen mit MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-CurrentFile_Delphi.jpg&amp;diff=215160</id>
		<title>Datei:Code Editor-CurrentFile Delphi.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-CurrentFile_Delphi.jpg&amp;diff=215160"/>
		<updated>2021-10-08T21:15:02Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: Datei hochgeladen mit MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Datei hochgeladen mit MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-CurrentFile_C%2B%2B.jpg&amp;diff=215159</id>
		<title>Datei:Code Editor-CurrentFile C++.jpg</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Datei:Code_Editor-CurrentFile_C%2B%2B.jpg&amp;diff=215159"/>
		<updated>2021-10-08T21:14:50Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: Datei hochgeladen mit MsUpload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Datei hochgeladen mit MsUpload&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Deklaration_von_Generics&amp;diff=215143</id>
		<title>Deklaration von Generics</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Deklaration_von_Generics&amp;diff=215143"/>
		<updated>2021-07-30T16:42:51Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: RS-107222&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Generics - Index}}&lt;br /&gt;
Die Deklaration von Generics ist vergleichbar mit der Deklaration von regulären Klassen-, Record- oder Interface-Typen. Der Unterschied besteht darin, dass die Deklaration von Generics eine Liste mit einem oder mehreren Typparametern in spitzen Klammern (&amp;amp;lt; und &amp;amp;gt;) nach dem Typbezeichner enthält.&lt;br /&gt;
&lt;br /&gt;
Ein Typparameter kann als typischer Typbezeichner innerhalb der Container-Typdeklaration und im Methodenrumpf verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TPair&amp;lt;TKey,TValue&amp;gt; = class   // TKey and TValue are type parameters&lt;br /&gt;
     FKey: TKey;&lt;br /&gt;
     FValue: TValue;&lt;br /&gt;
     function GetValue: TValue;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 function TPair&amp;lt;TKey,TValue&amp;gt;.GetValue: TValue;&lt;br /&gt;
 begin&lt;br /&gt;
   Result := FValue;&lt;br /&gt;
 end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Vor dem Aufruf der Methode &#039;&#039;&#039;GetValue&#039;&#039;&#039; müssen Sie den Standardkonstruktor aufrufen und die Klassenfelder initialisieren.}}&lt;br /&gt;
&lt;br /&gt;
==Typargument==&lt;br /&gt;
&lt;br /&gt;
Generische Typen werden durch das Bereitstellen von Typargumenten instantiiert. In {{Delphi}} können Sie jeden beliebigen Typ außer den folgenden als Typargument verwenden: ein statisches Array, ein Short String oder ein Record-Typ, der ein Feld mit einem oder mehreren dieser beiden Typen (rekursiv) enthält.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class&lt;br /&gt;
     FData: T;&lt;br /&gt;
   end;&lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo&amp;lt;Integer&amp;gt;; // &#039;Integer&#039; is the type argument of TFoo&amp;lt;T&amp;gt;&lt;br /&gt;
 begin&lt;br /&gt;
   ...&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Verschachtelte Typen==&lt;br /&gt;
&lt;br /&gt;
Ein in einem generischen Typ verschachtelter Typ ist selbst ein generischer Typ.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TFoo&amp;lt;T&amp;gt; = class                   // A generic class&lt;br /&gt;
  type&lt;br /&gt;
    TBar = class&lt;br /&gt;
      X: Integer;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um auf den verschachtelten Typ TBar zuzugreifen, müssen Sie zuerst eine Konstruktion des Typs TFoo angeben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 var&lt;br /&gt;
   N: TFoo&amp;lt;Double&amp;gt;.TBar;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Ein generischer Typ kann auch in einer regulären Klasse als verschachtelter Typ deklariert werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type &lt;br /&gt;
 TBaz = class                        // A regular class&lt;br /&gt;
  type&lt;br /&gt;
    TQux&amp;lt;T&amp;gt; = class&lt;br /&gt;
      X: Integer;&lt;br /&gt;
    end;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
 type&lt;br /&gt;
   TOuter = class&lt;br /&gt;
   type&lt;br /&gt;
     TData&amp;lt;T&amp;gt; = class&lt;br /&gt;
       FFoo1: TFoo&amp;lt;Integer&amp;gt;;         // declared with closed constructed type&lt;br /&gt;
       FFoo2: TFoo&amp;lt;T&amp;gt;;               // declared with open constructed type&lt;br /&gt;
       FFooBar1: TFoo&amp;lt;Integer&amp;gt;.TBar; // declared with closed constructed type&lt;br /&gt;
       FFooBar2: TFoo&amp;lt;T&amp;gt;.TBar;       // declared with open constructed type&lt;br /&gt;
       FBazQux1: TBaz.TQux&amp;lt;Integer&amp;gt;; // declared with closed constructed type&lt;br /&gt;
       FBazQux2: TBaz.TQux&amp;lt;T&amp;gt;;       // declared with open constructed type&lt;br /&gt;
       ...&lt;br /&gt;
     end;&lt;br /&gt;
   var&lt;br /&gt;
     FIntegerData: TData&amp;lt;Integer&amp;gt;;&lt;br /&gt;
     FStringData: TData&amp;lt;String&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Basistypen==&lt;br /&gt;
&lt;br /&gt;
Der Basistyp eines parametrisierten Klassen- oder Interface-Typs kann ein tatsächlicher Typ oder ein konstruierter Typ sein. Der Basistyp darf kein Typparameter sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
  type&lt;br /&gt;
    TFoo1&amp;lt;T&amp;gt; = class(TBar)            // Actual type&lt;br /&gt;
    end;&lt;br /&gt;
 &lt;br /&gt;
    TFoo2&amp;lt;T&amp;gt; =  class(TBar2&amp;lt;T&amp;gt;)       // Open constructed type&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    TFoo3&amp;lt;T&amp;gt; = class(TBar3&amp;lt;Integer&amp;gt;)  // Closed constructed type&lt;br /&gt;
    end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Wenn TFoo2&amp;amp;lt;String&amp;amp;gt; instantiiert ist, wird eine Vorfahrklasse zu TBar2&amp;amp;lt;String&amp;amp;gt;, und TBar2&amp;amp;lt;String&amp;amp;gt; wird automatisch instantiiert.&lt;br /&gt;
&lt;br /&gt;
==Klassen-, Interface- und Record-Typen==&lt;br /&gt;
&lt;br /&gt;
Klassen-, Interface-, Record- und Array-Typen können mit Typparametern deklariert werden.&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TRecord&amp;lt;T&amp;gt; = record&lt;br /&gt;
     FData: T;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
   IAncestor&amp;lt;T&amp;gt; = interface&lt;br /&gt;
     function GetRecord: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
   IFoo&amp;lt;T&amp;gt; = interface(IAncestor&amp;lt;T&amp;gt;)&lt;br /&gt;
     procedure AMethod(Param: T);&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class(TObject, IFoo&amp;lt;T&amp;gt;)&lt;br /&gt;
     FField: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
     procedure AMethod(Param: T);&lt;br /&gt;
     function GetRecord: TRecord&amp;lt;T&amp;gt;;&lt;br /&gt;
   end;&lt;br /&gt;
&lt;br /&gt;
 type&lt;br /&gt;
   anArray&amp;lt;T&amp;gt;= array of T;&lt;br /&gt;
   IntArray= anArray&amp;lt;integer&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prozedurale Typen==&lt;br /&gt;
&lt;br /&gt;
Prozedurale Typen und Methodenzeiger können mit Typparametern deklariert werden. Parametertypen und Ergebnistypen können auch Typparameter verwenden.&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TMyProc&amp;lt;T&amp;gt; = procedure(Param: T);&lt;br /&gt;
   TMyProc2&amp;lt;Y&amp;gt; = procedure(Param1, Param2: Y) of object;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo = class&lt;br /&gt;
     procedure Test;&lt;br /&gt;
     procedure MyProc(X, Y: Integer);&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 procedure Sample(Param: Integer);&lt;br /&gt;
 begin&lt;br /&gt;
   Writeln(Param);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 procedure TFoo.MyProc(X, Y: Integer);&lt;br /&gt;
 begin&lt;br /&gt;
   Writeln(&#039;X:&#039;, X, &#039;, Y:&#039;, Y);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 procedure TFoo.Test;&lt;br /&gt;
 var&lt;br /&gt;
   X: TMyProc&amp;lt;Integer&amp;gt;;&lt;br /&gt;
   Y: TMyProc2&amp;lt;Integer&amp;gt;;&lt;br /&gt;
 begin&lt;br /&gt;
   X := Sample;&lt;br /&gt;
   X(10);&lt;br /&gt;
   Y := MyProc;&lt;br /&gt;
   Y(20, 30);&lt;br /&gt;
 end;&lt;br /&gt;
 &lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo;&lt;br /&gt;
 begin&lt;br /&gt;
   F := TFoo.Create;&lt;br /&gt;
   F.Test;&lt;br /&gt;
   F.Free;&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parametrisierte Methoden==&lt;br /&gt;
&lt;br /&gt;
Methoden können mit Typparametern deklariert werden. Parametertypen und Ergebnistypen können Typparameter verwenden. Konstruktoren und Destruktoren sowie virtuelle, dynamische oder Botschaftsmethoden dürfen allerdings keine Typparameter haben. Parametrisierte Methoden sind mit überladenen Methoden vergleichbar.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten, eine Methode zu instantiieren:&lt;br /&gt;
&lt;br /&gt;
* Durch die explizite Angabe eines Typarguments&lt;br /&gt;
* Durch automatische Ableitung vom Typargument &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TFoo = class&lt;br /&gt;
    procedure Test;&lt;br /&gt;
    procedure CompareAndPrintResult&amp;lt;T&amp;gt;(X, Y: T);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
procedure TFoo.CompareAndPrintResult&amp;lt;T&amp;gt;(X, Y: T);&lt;br /&gt;
var&lt;br /&gt;
  Comparer : IComparer&amp;lt;T&amp;gt;;&lt;br /&gt;
begin&lt;br /&gt;
  Comparer := TComparer&amp;lt;T&amp;gt;.Default;&lt;br /&gt;
  if Comparer.Compare(X, Y) = 0 then&lt;br /&gt;
    WriteLn(&#039;Both members compare as equal&#039;)&lt;br /&gt;
  else&lt;br /&gt;
    WriteLn(&#039;Members do not compare as equal&#039;);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TFoo.Test;&lt;br /&gt;
begin&lt;br /&gt;
  CompareAndPrintResult&amp;lt;String&amp;gt;(&#039;Hello&#039;, &#039;World&#039;);&lt;br /&gt;
  CompareAndPrintResult(&#039;Hello&#039;, &#039;Hello&#039;);&lt;br /&gt;
  CompareAndPrintResult&amp;lt;Integer&amp;gt;(20, 20);&lt;br /&gt;
  CompareAndPrintResult(10, 20);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  F: TFoo;&lt;br /&gt;
begin&lt;br /&gt;
  F := TFoo.Create;&lt;br /&gt;
  F.Test;&lt;br /&gt;
  ReadLn;&lt;br /&gt;
  F.Free;&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gültigkeitsbereich von Typparametern==&lt;br /&gt;
&lt;br /&gt;
Der Gültigkeitsbereich eines Typparameters umfasst die Typdeklaration und den Rumpf aller Member, aber keine abgeleiteten Typen.&lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
 type&lt;br /&gt;
   TFoo&amp;lt;T&amp;gt; = class&lt;br /&gt;
     X: T;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
   TBar&amp;lt;S&amp;gt; = class(TFoo&amp;lt;S&amp;gt;)&lt;br /&gt;
     Y: T;  // error!  unknown identifier &amp;quot;T&amp;quot;&lt;br /&gt;
   end;&lt;br /&gt;
 &lt;br /&gt;
 var&lt;br /&gt;
   F: TFoo&amp;lt;Integer&amp;gt;;&lt;br /&gt;
 begin&lt;br /&gt;
   F.T  // error! unknown identifier &amp;quot;T&amp;quot;&lt;br /&gt;
 end.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
*[[Übersicht über Generics|Übersicht über Generics]]&lt;br /&gt;
*[[Terminologie für Generics|Terminologie für Generics]]&lt;br /&gt;
*[[Einschränkungen bei Generics (Parametrisierte Typen)|Einschränkungen bei Generics]]&lt;br /&gt;
*[[Overloads und Typkompatibilität in Generics|Overloads und Typkompatibilität in Generics]]&lt;br /&gt;
*[[Klassenvariablen in Generics|Klassenvariablen in Generics]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:Delphi-Sprachreferenz]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Declaring Generics]]&lt;br /&gt;
[[fr:Déclaration des génériques]]&lt;br /&gt;
[[ja:ジェネリックスの宣言]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Eigenschaften_(Delphi)&amp;diff=215139</id>
		<title>Eigenschaften (Delphi)</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Eigenschaften_(Delphi)&amp;diff=215139"/>
		<updated>2021-06-29T20:05:19Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Speicherbezeichner */ RS-107569&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Klassen und Objekte - Index}}&lt;br /&gt;
{{DISPLAYTITLE:Eigenschaften ({{Delphi}})}}&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;property&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;type&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;integerConstant&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;read&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;write&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;stored&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;default&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;nodedefault&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;implements&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;var&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;virtual&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;register&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;dynamic&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;const&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;index&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;True&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;False&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;Boolean&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;nil&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;&#039;&#039;&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;class property&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;published&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;class var&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;public&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;private&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;protected&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;strict private&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
&amp;lt;ideTag id=&amp;quot;strict protected&amp;quot;&amp;gt;&amp;lt;/ideTag&amp;gt;&lt;br /&gt;
Dieses Thema enthält Informationen zu folgenden Bereichen:&lt;br /&gt;
&lt;br /&gt;
* Auf Eigenschaften zugreifen&lt;br /&gt;
* Array-Eigenschaften&lt;br /&gt;
* Indexbezeichner&lt;br /&gt;
* Speicherbezeichner&lt;br /&gt;
* Eigenschaften überschreiben und neu deklarieren&lt;br /&gt;
* Klasseneigenschaften&lt;br /&gt;
&lt;br /&gt;
==Allgemeines zu Eigenschaften==&lt;br /&gt;
&lt;br /&gt;
Eine Eigenschaft definiert wie ein Feld ein Objektattribut. Felder sind jedoch nur Speicherbereiche, die überprüft und geändert werden können, während Eigenschaften mithilfe bestimmter Aktionen gelesen und geschrieben werden können. Sie erlauben eine größere Kontrolle über den Zugriff auf die Attribute eines Objekts und ermöglichen das Berechnen von Attributen.&lt;br /&gt;
&lt;br /&gt;
Die Deklaration einer Eigenschaft muss einen Namen, einen Typ und mindestens eine Zugriffsangabe enthalten. Die Syntax lautet folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;property &#039;&#039;&#039;&#039;&#039;Eigenschaftsname[Indizes]: Typ &#039;&#039;&amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;index&amp;lt;/span&amp;gt;&#039;&#039; Integer-Konstante Bezeichner;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
wobei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Eigenschaftsname&#039;&#039; ein beliebiger gültiger Bezeichner ist.&lt;br /&gt;
* &#039;&#039;[Indizes]&#039;&#039; ist optional und besteht aus einer Folge von durch Strichpunkte getrennten Parameterdeklarationen. Jede Deklaration hat die Form &#039;&#039;Bezeichner1&#039;&#039;, ..., &#039;&#039;Bezeichnern&#039;&#039;: Typ. Weitere Informationen finden Sie im Abschnitt &amp;quot;Array-Eigenschaften&amp;quot; weiter unten.&lt;br /&gt;
* &#039;&#039;Typ&#039;&#039; muss ein vordefinierter oder vorher deklarierter Typbezeichner sein. Eigenschaftsdeklarationen der Form &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;property Num: 0..9&amp;lt;/span&amp;gt; sind somit unzulässig.&lt;br /&gt;
* Die Indexklausel &#039;&#039;Integer-Konstante&#039;&#039; ist optional. Weitere Informationen hierzu finden Sie im Abschnitt &amp;quot;Indexbezeichner&amp;quot; weiter unten.&lt;br /&gt;
* &#039;&#039;Bezeichner&#039;&#039; besteht aus den Bezeichnern &#039;&#039;&#039;read&#039;&#039;&#039;, &#039;&#039;&#039;write&#039;&#039;&#039;, &#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; (oder &#039;&#039;&#039;nodefault&#039;&#039;&#039;) und &#039;&#039;&#039;implements&#039;&#039;&#039;. Jede Eigenschaftsdeklaration muss zumindest einen &#039;&#039;&#039;read&#039;&#039;&#039;- oder &#039;&#039;&#039;write&#039;&#039;&#039;-Bezeichner enthalten.&lt;br /&gt;
&lt;br /&gt;
Eigenschaften werden durch ihre Zugriffsbezeichner definiert. Sie können im Gegensatz zu Feldern nicht als &#039;&#039;&#039;var&#039;&#039;&#039;-Parameter übergeben oder mit dem Adressoperator &#039;&#039;&#039;@&#039;&#039;&#039; versehen werden. Der Grund dafür liegt darin, dass eine Eigenschaft nicht notwendigerweise im Speicher vorhanden sein muss. Sie kann beispielsweise eine &#039;&#039;&#039;read&#039;&#039;&#039;-Methode haben, die einen Wert aus einer Datenbank abruft oder einen Zufallswert generiert.&lt;br /&gt;
&lt;br /&gt;
==Auf Eigenschaften zugreifen==&lt;br /&gt;
&lt;br /&gt;
Jede Eigenschaft verfügt über eine &#039;&#039;&#039;read&#039;&#039;&#039;- oder eine &#039;&#039;&#039;write&#039;&#039;&#039;-Angabe (oder über beide). Diese Zugriffsbezeichner werden in folgender Form angegeben:&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;read &#039;&#039;&#039;&#039;&#039;FeldOderMethode&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;write &#039;&#039;&#039;&#039;&#039;FeldOderMethode&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;FeldOderMethode&#039;&#039; ist der Name eines Feldes oder einer Methode, das bzw. die in derselben Klasse oder in einer Vorfahrklasse der Eigenschaft deklariert ist.&lt;br /&gt;
&lt;br /&gt;
* Wenn &#039;&#039;FeldOderMethode&#039;&#039; in derselben Klasse deklariert wird, muss dies vor der Eigenschaft geschehen. Ist das Element in einer Vorfahrklasse deklariert, muss es in der abgeleiteten Klasse sichtbar sein. Es kann also kein Element einer abgeleiteten Klasse angegeben werden, das in einer anderen Unit als &#039;&#039;&#039;private&#039;&#039;&#039; deklariert ist.&lt;br /&gt;
* Handelt es sich bei &#039;&#039;FeldOderMethode&#039;&#039; um ein Feld, muss dieses Feld denselben Typ wie die Eigenschaft haben.&lt;br /&gt;
* Wenn &#039;&#039;FeldOderMethode&#039;&#039; eine Methode ist, kann diese nicht &#039;&#039;&#039;dynamic&#039;&#039;&#039; sein. Falls es sich um eine &#039;&#039;&#039;virtual&#039;&#039;&#039; Methode handelt, kann diese nicht überladen werden. Zugriffsmethoden für eine als &#039;&#039;&#039;published&#039;&#039;&#039; deklarierte Eigenschaft müssen die Standard-Aufrufkonvention &#039;&#039;&#039;register&#039;&#039;&#039; verwenden.&lt;br /&gt;
* Wird in einem &#039;&#039;&#039;read&#039;&#039;&#039;-Bezeichner für &#039;&#039;FeldOderMethode&#039;&#039; eine Methode angegeben, muss eine Funktion ohne Parameter verwendet werden, die einen Wert mit dem Typ der Eigenschaft zurückgibt. Eine Ausnahme bildet die Zugriffsmethode für eine indizierte Eigenschaft oder eine Array-Eigenschaft.&lt;br /&gt;
* Wird in einem &#039;&#039;&#039;write&#039;&#039;&#039;-Bezeichner für &#039;&#039;FeldOderMethode&#039;&#039; eine Methode angegeben, muss eine Prozedur verwendet werden, die einen Wert- oder &#039;&#039;&#039;const&#039;&#039;&#039;-Parameter mit dem Datentyp der Eigenschaft entgegennimmt (oder wenn es sich um eine Array-Eigenschaft oder indizierte Eigenschaft handelt).&lt;br /&gt;
&lt;br /&gt;
Betrachten Sie beispielsweise die folgende Deklaration:&lt;br /&gt;
&lt;br /&gt;
 property Color: TColor read GetColor write SetColor;&lt;br /&gt;
&lt;br /&gt;
Die Methode &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;GetColor&amp;lt;/span&amp;gt; muss hier folgendermaßen deklariert werden:&lt;br /&gt;
&lt;br /&gt;
 function GetColor: TColor;&lt;br /&gt;
&lt;br /&gt;
Die Deklaration der Methode &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;SetColor&amp;lt;/span&amp;gt; muss eine der folgenden Formen haben:&lt;br /&gt;
 &lt;br /&gt;
 procedure SetColor(Value: TColor);&lt;br /&gt;
 procedure SetColor(const Value: TColor);&lt;br /&gt;
&lt;br /&gt;
(Der Parameter von &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;SetColor&amp;lt;/span&amp;gt; muss natürlich nicht unbedingt &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Value&amp;lt;/span&amp;gt; heißen.)&lt;br /&gt;
&lt;br /&gt;
Wenn eine Eigenschaft in einem Ausdruck verwendet wird, erfolgt der Zugriff auf ihren Wert mithilfe des mit &#039;&#039;&#039;read&#039;&#039;&#039; angegebenen Elements (Feld oder Methode). Bei Zuweisungen wird das mit &#039;&#039;&#039;write&#039;&#039;&#039; angegebene Element für das Schreiben der Eigenschaft verwendet.&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird die Klasse &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;TCompass&amp;lt;/span&amp;gt; mit der &#039;&#039;&#039;published&#039;&#039;&#039;-Eigenschaft &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt; deklariert. Zum Lesen der Eigenschaft wird das Feld &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt;, zum Schreiben die Prozedur &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt; verwendet.&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    THeading = 0..359;&lt;br /&gt;
    TCompass = class(TControl)&lt;br /&gt;
      private&lt;br /&gt;
         FHeading: THeading;&lt;br /&gt;
         procedure SetHeading(Value: THeading);&lt;br /&gt;
      published&lt;br /&gt;
         property Heading: THeading read FHeading write SetHeading;&lt;br /&gt;
         ...&lt;br /&gt;
     end;&lt;br /&gt;
&lt;br /&gt;
Ausgehend von dieser Deklaration ist die Anweisung&lt;br /&gt;
 &lt;br /&gt;
 if Compass.Heading = 180 then GoingSouth;&lt;br /&gt;
 Compass.Heading := 135;&lt;br /&gt;
&lt;br /&gt;
mit den folgenden Anweisungen identisch:&lt;br /&gt;
 &lt;br /&gt;
 if Compass.FHeading = 180 then GoingSouth;&lt;br /&gt;
 Compass.SetHeading(135);&lt;br /&gt;
&lt;br /&gt;
In der Klasse &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;TCompass&amp;lt;/span&amp;gt; wird zum Lesen der Eigenschaft &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Heading&amp;lt;/span&amp;gt; keine bestimmte Aktion verwendet. Die &#039;&#039;&#039;read&#039;&#039;&#039;-Operation besteht lediglich aus dem Abrufen des im Feld &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt; gespeicherten Wertes. Wertzuweisungen an die Eigenschaft werden in Aufrufe der Methode &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt; umgesetzt. Diese Methode speichert den neuen Wert im Feld &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;FHeading&amp;lt;/span&amp;gt; und führt optional weitere Operationen durch. &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;SetHeading&amp;lt;/span&amp;gt; könnte beispielsweise folgendermaßen implementiert werden:&lt;br /&gt;
 &lt;br /&gt;
 procedure TCompass.SetHeading(Value: THeading);&lt;br /&gt;
 begin&lt;br /&gt;
             if FHeading &amp;amp;lt;&amp;amp;gt; Value then&lt;br /&gt;
              begin&lt;br /&gt;
                FHeading := Value;&lt;br /&gt;
                Repaint;    // Aktualisieren der Benutzeroberfläche, um den neuen Wert anzuzeigen&lt;br /&gt;
              end;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
Eine Eigenschaft, die nur mit einer &#039;&#039;&#039;read&#039;&#039;&#039;-Angabe deklariert ist, nennt man Nur-Lesen-Eigenschaft (schreibgeschützt). Ist nur ein &#039;&#039;&#039;write&#039;&#039;&#039;-Bezeichner vorhanden, handelt es sich um eine Nur-Schreiben-Eigenschaft (lesegeschützt). Wenn Sie einer Nur-Lesen-Eigenschaft einen Wert zuweisen oder eine Nur-Schreiben-Eigenschaft in einem Ausdruck verwenden, tritt ein Fehler auf.&lt;br /&gt;
&lt;br /&gt;
==Array-Eigenschaften==&lt;br /&gt;
&lt;br /&gt;
Array-Eigenschaften sind indizierte Eigenschaften. Sie werden beispielsweise für die Einträge eines Listenfeldes, die untergeordneten Objekte eines Steuerelements oder die Pixel einer Bitmap-Grafik verwendet.&lt;br /&gt;
&lt;br /&gt;
Die Deklaration einer Array-Eigenschaft enthält eine Parameterliste mit den Namen und Typen der Indizes. Beispiel:&lt;br /&gt;
 &lt;br /&gt;
 property Objects[Index: Integer]: TObject read GetObject write SetObject;&lt;br /&gt;
 property Pixels[X, Y: Integer]: TColor read GetPixel write SetPixel;&lt;br /&gt;
 property Values[const Name: string]: string read GetValue write SetValue;&lt;br /&gt;
&lt;br /&gt;
Das Format der Liste ist mit dem Format der Parameterliste einer Prozedur oder Funktion identisch. Der einzige Unterschied besteht darin, dass die Parameterdeklarationen nicht in runden, sondern in eckigen Klammern angegeben werden. Im Gegensatz zu Arrays, bei denen nur ordinale Indizes erlaubt sind, können die Indizes von Array-Eigenschaften einen beliebigen Typ haben.&lt;br /&gt;
&lt;br /&gt;
Bei Array-Eigenschaften müssen die Zugriffsbezeichner keine Felder, sondern Methoden angeben. Die Methode in einem &#039;&#039;&#039;read&#039;&#039;&#039;-Bezeichner muss eine Funktion sein, bei der Anzahl, Reihenfolge und Typ der Parameter mit der Indexparameterliste der Eigenschaft identisch sind, und der Ergebnistyp mit dem Typ der Eigenschaft übereinstimmt. Die Methode in einem &#039;&#039;&#039;write&#039;&#039;&#039;-Bezeichner muss eine Prozedur sein, bei der Anzahl, Reihenfolge und Typ der Parameter mit der Indexparameterliste der Eigenschaft identisch sind. Außerdem muss ein zusätzlicher Wert- oder &#039;&#039;&#039;const&#039;&#039;&#039;-Parameter mit dem Typ der Eigenschaft vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
Die Zugriffsmethoden für die obigen Array-Eigenschaften können beispielsweise folgendermaßen deklariert werden:&lt;br /&gt;
 &lt;br /&gt;
 function GetObject(Index: Integer): TObject;&lt;br /&gt;
 function GetPixel(X, Y: Integer): TColor;&lt;br /&gt;
 function GetValue(const Name: string): string;&lt;br /&gt;
 procedure SetObject(Index: Integer; Value: TObject);&lt;br /&gt;
 procedure SetPixel(X, Y: Integer; Value: TColor);&lt;br /&gt;
 procedure SetValue(const Name, Value: string);&lt;br /&gt;
&lt;br /&gt;
Auf eine Array-Eigenschaft kann durch Indizieren ihres Bezeichners zugegriffen werden. So sind beispielsweise die Anweisungen&lt;br /&gt;
 &lt;br /&gt;
 if Collection.Objects[0] = nil then Exit;&lt;br /&gt;
 Canvas.Pixels[10, 20] := clRed;&lt;br /&gt;
 Params.Values[&#039;PATH&#039;] := &#039;C:\BIN&#039;;&lt;br /&gt;
&lt;br /&gt;
mit den folgenden Anweisungen identisch:&lt;br /&gt;
 &lt;br /&gt;
 if Collection.GetObject(0) = nil then Exit;&lt;br /&gt;
 Canvas.SetPixel(10, 20, clRed);&lt;br /&gt;
 Params.SetValue(&#039;PATH&#039;, &#039;C:\BIN&#039;);&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die Direktive &#039;&#039;&#039;default&#039;&#039;&#039; nach der Definition einer Array-Eigenschaft angeben, wird diese als Standardeigenschaft der betreffenden Klasse verwendet. Beispiel:&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TStringArray = class&lt;br /&gt;
     public&lt;br /&gt;
        property Strings[Index: Integer]: string ...; default;&lt;br /&gt;
           ...&lt;br /&gt;
     end;&lt;br /&gt;
&lt;br /&gt;
Auf die Array-Standardeigenschaft einer Klasse kann mit der Kurzform &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Objekt[Index]&amp;lt;/span&amp;gt; zugegriffen werden. Diese Anweisung ist mit &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Objekt.Eigenschaft[Index]&amp;lt;/span&amp;gt; identisch. Ausgehend von der vorhergehenden Deklaration kann z.B. &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;StringArray.Strings[7]&amp;lt;/span&amp;gt; zu &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;StringArray[7]&amp;lt;/span&amp;gt; verkürzt werden. Eine Klasse kann nur eine Standardeigenschaft mit der gegebenen Signatur (Array-Parameterliste) haben, aber es ist möglich, die Standardeigenschaft zu überladen. Das Ändern oder Verbergen der Standardeigenschaft in abgeleiteten Klassen kann zu unerwünschten Ergebnissen führen, da der Compiler Bindungen an Eigenschaften immer statisch vornimmt.&lt;br /&gt;
&lt;br /&gt;
==Indexbezeichner==&lt;br /&gt;
&lt;br /&gt;
Mithilfe von Indexbezeichnern können mehrere Eigenschaften dieselbe Zugriffsmethode verwenden, auch wenn sie unterschiedliche Werte repräsentieren. Indexbezeichner bestehen aus der Direktive &#039;&#039;&#039;index&#039;&#039;&#039; und einem Integer-Wert zwischen -2.147.483.647 und 2.147.483.647. Bei Eigenschaften mit Indexbezeichnern muss auf die Direktiven &#039;&#039;&#039;read&#039;&#039;&#039; und &#039;&#039;&#039;write&#039;&#039;&#039; eine Methode (kein Feld) folgen. Beispiel:&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TRectangle = class&lt;br /&gt;
      private&lt;br /&gt;
        FCoordinates: array[0..3] of Longint;&lt;br /&gt;
        function GetCoordinate(Index: Integer): Longint;&lt;br /&gt;
        procedure SetCoordinate(Index: Integer; Value: Longint);&lt;br /&gt;
      public&lt;br /&gt;
        property Left: Longint index 0  read GetCoordinate &lt;br /&gt;
                                        write SetCoordinate;&lt;br /&gt;
        property Top: Longint index 1   read GetCoordinate &lt;br /&gt;
                                        write SetCoordinate;&lt;br /&gt;
        property Right: Longint index 2 read GetCoordinate&lt;br /&gt;
                                        write SetCoordinate;&lt;br /&gt;
        property Bottom: Longint index 3 read GetCoordinate&lt;br /&gt;
                                         write SetCoordinate;&lt;br /&gt;
        property Coordinates[Index: Integer]: Longint &lt;br /&gt;
                                        read GetCoordinate&lt;br /&gt;
                                        write SetCoordinate;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
Eine Zugriffsmethode für eine Eigenschaft mit einem Indexbezeichner benötigt einen zusätzlichen Wert-Parameter vom Typ Integer. Bei einer &#039;&#039;&#039;read&#039;&#039;&#039;-Funktion muss dies der letzte, bei einer &#039;&#039;&#039;write&#039;&#039;&#039;-Prozedur der vorletzte Parameter sein. Diese Konstante (der Index) wird beim Zugriff auf die Eigenschaft automatisch an die Zugriffsmethode übergeben.&lt;br /&gt;
&lt;br /&gt;
Wenn &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Rectangle&amp;lt;/span&amp;gt; ein Objekt der zuvor deklarierten Klasse &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;TRectangle&amp;lt;/span&amp;gt; ist, dann ist die Anweisung&lt;br /&gt;
&lt;br /&gt;
 Rectangle.Right := Rectangle.Left + 100;&lt;br /&gt;
&lt;br /&gt;
mit der folgenden Anweisung identisch:&lt;br /&gt;
&lt;br /&gt;
 Rectangle.SetCoordinate(2, Rectangle.GetCoordinate(0) + 100);&lt;br /&gt;
&lt;br /&gt;
==Speicherbezeichner==&lt;br /&gt;
&lt;br /&gt;
Die optionalen Direktiven &#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; und &#039;&#039;&#039;nodefault&#039;&#039;&#039; sind Speicherbezeichner. Sie haben keinerlei Auswirkungen auf die Funktionsweise des Programms, sondern bestimmen, ob die Werte der &#039;&#039;&#039;published&#039;&#039;&#039;-Eigenschaften in Formulardateien gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Nach der Angabe &#039;&#039;&#039;stored&#039;&#039;&#039; muss der Wert &#039;&#039;&#039;True&#039;&#039;&#039; oder &#039;&#039;&#039;False&#039;&#039;&#039;, der Name eines booleschen Feldes oder der Name einer parameterlosen Methode folgen, die einen booleschen Wert zurückgibt. Beispiel:&lt;br /&gt;
&lt;br /&gt;
 property Name : TComponentName read FName write SetName stored False;&lt;br /&gt;
&lt;br /&gt;
Wird eine Eigenschaft ohne die Angabe von &#039;&#039;&#039;stored&#039;&#039;&#039; deklariert, entspricht dies der Definition &#039;&#039;&#039;stored&#039;&#039;&#039; &#039;&#039;&#039;True&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Nach &#039;&#039;&#039;default&#039;&#039;&#039; muss eine Konstante angegeben werden, die denselben Datentyp wie die Eigenschaft hat. Beispiel:&lt;br /&gt;
&lt;br /&gt;
 property Tag: Longint read FTag write FTag default 0;&lt;br /&gt;
&lt;br /&gt;
Mithilfe des Bezeichners &#039;&#039;&#039;nodefault&#039;&#039;&#039; kann ein geerbter &#039;&#039;&#039;default&#039;&#039;&#039;-Wert ohne Angabe eines neues Wertes außer Kraft gesetzt werden. Die Direktiven &#039;&#039;&#039;default&#039;&#039;&#039; und &#039;&#039;&#039;nodefault&#039;&#039;&#039; werden nur für Ordinal- und Mengentypen unterstützt, bei denen die Ober- und Untergrenze des Basistyps einen Ordinalwert zwischen 0 und 31 hat. Enthält eine Eigenschaftsdeklaration weder &#039;&#039;&#039;default&#039;&#039;&#039; noch &#039;&#039;&#039;nodefault&#039;&#039;&#039;, gilt sie als mit &#039;&#039;&#039;nodefault&#039;&#039;&#039; definiert. Für Real-, Zeiger- und String-Typen gilt der implizite &#039;&#039;&#039;default&#039;&#039;&#039;-Wert 0 bzw. &#039;&#039;&#039;nil&#039;&#039;&#039; und &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt; (leerer String).&lt;br /&gt;
&lt;br /&gt;
{{Note| Sie können den ordinalen Wert -2147483648 nicht als Standardwert verwenden. Dieser Wert wird intern für die Darstellung von &#039;&#039;&#039;nodefault&#039;&#039;&#039; verwendet.}}&lt;br /&gt;
&lt;br /&gt;
Beim Speichern einer Komponente werden die Speicherbezeichner ihrer &#039;&#039;&#039;published&#039;&#039;&#039;-Eigenschaften überprüft. Wenn sich der aktuelle Wert einer Eigenschaft von ihrem &#039;&#039;&#039;default&#039;&#039;&#039;-Wert unterscheidet (oder kein &#039;&#039;&#039;default&#039;&#039;&#039;-Wert vorhanden ist) und &#039;&#039;&#039;stored&#039;&#039;&#039; &#039;&#039;&#039;True&#039;&#039;&#039; ist, wird der Wert gespeichert. Treffen diese Bedingungen nicht zu, wird der Wert nicht gespeichert.&lt;br /&gt;
&lt;br /&gt;
{{Note| Eigenschaftswerte werden nicht automatisch auf den Standardwert initialisiert, d.h. die Standarddirektive steuert nur das Speichern von Eigenschaftswerten in der Formulardatei und nicht das Speichern des ersten Werts der Eigenschaft in einer neu erstellten Instanz.}}&lt;br /&gt;
&lt;br /&gt;
Bei Array-Eigenschaften werden Speicherbezeichner nicht unterstützt. Bei diesem Eigenschaftstyp hat &#039;&#039;&#039;default&#039;&#039;&#039; eine andere Bedeutung (siehe &amp;quot;Array-Eigenschaften&amp;quot; weiter oben).&lt;br /&gt;
&lt;br /&gt;
==Eigenschaften überschreiben und neu deklarieren==&lt;br /&gt;
&lt;br /&gt;
Das Deklarieren einer Eigenschaft ohne Angabe eines Typs nennt man Überschreiben. Diese Vorgehensweise ermöglicht das Ändern der geerbten Sichtbarkeit bzw. des geerbten Bezeichners einer Eigenschaft. In der einfachsten Form braucht nur das reservierte Wort &#039;&#039;&#039;property&#039;&#039;&#039; zusammen mit einem geerbten Eigenschaftsbezeichner angegeben zu werden. Auf diese Weise kann die Sichtbarkeit der betreffenden Eigenschaft geändert werden. So kann beispielsweise eine in einer Vorfahrklasse als &#039;&#039;&#039;protected&#039;&#039;&#039; deklarierte Eigenschaft im &#039;&#039;&#039;public&#039;&#039;&#039;- oder &#039;&#039;&#039;published&#039;&#039;&#039;-Abschnitt einer abgeleiteten Klasse neu deklariert werden. Eigenschaftsüberschreibungen können die Angaben &#039;&#039;&#039;read&#039;&#039;&#039;, &#039;&#039;&#039;write&#039;&#039;&#039;,&#039;&#039;&#039;stored&#039;&#039;&#039;, &#039;&#039;&#039;default&#039;&#039;&#039; und &#039;&#039;&#039;nodefault&#039;&#039;&#039; enthalten, durch die die entsprechende geerbte Direktive außer Kraft gesetzt wird. Mithilfe einer Überschreibung können Sie geerbte Zugriffsangaben ersetzen, fehlende Angaben hinzufügen oder den Gültigkeitsbereich einer Eigenschaft erweitern, jedoch keine Zugriffsbezeichner entfernen oder die Sichtbarkeit verringern. Optional kann auch mit der Direktive &#039;&#039;&#039;implements&#039;&#039;&#039; die Liste der implementierten Interfaces ergänzt werden, ohne die geerbten Interfaces zu entfernen.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Deklarationen zeigen, wie Eigenschaften überschrieben werden können:&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TAncestor = class&lt;br /&gt;
        ...&lt;br /&gt;
      protected&lt;br /&gt;
        property Size: Integer read FSize;&lt;br /&gt;
        property Text: string read GetText write SetText;&lt;br /&gt;
        property Color: TColor read FColor write SetColor stored False;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
 &lt;br /&gt;
    TDerived = class(TAncestor)&lt;br /&gt;
        ...&lt;br /&gt;
      protected&lt;br /&gt;
        property Size write SetSize;&lt;br /&gt;
      published&lt;br /&gt;
        property Text;&lt;br /&gt;
        property Color stored True default clBlue;&lt;br /&gt;
        ...&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
Beim Überschreiben von &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Size&amp;lt;/span&amp;gt; wird die Angabe &#039;&#039;&#039;write&#039;&#039;&#039; hinzugefügt, damit der Wert der Eigenschaft geändert werden kann. Die Sichtbarkeit der Eigenschaften &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Text&amp;lt;/span&amp;gt; und &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Color&amp;lt;/span&amp;gt; wird von &#039;&#039;&#039;protected&#039;&#039;&#039; in &#039;&#039;&#039;published&#039;&#039;&#039; geändert. Für die Eigenschaft &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Color&amp;lt;/span&amp;gt; wird außerdem festgelegt, dass sie in der Formulardatei gespeichert wird, wenn sie einen anderen Wert als &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;clBlue&amp;lt;/span&amp;gt; hat.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie beim Redeklarieren einer Eigenschaft einen Typbezeichner angeben, wird die geerbte Eigenschaft nicht überschrieben, sondern lediglich verdeckt. Dadurch wird eine neue Eigenschaft mit demselben Namen wie die geerbte erstellt. Diese Art der Deklaration muss immer vollständig vorgenommen werden. Stets muss zumindest eine Zugriffsangabe vorhanden sein.&lt;br /&gt;
&lt;br /&gt;
Unabhängig davon, ob eine Eigenschaft in einer abgeleiteten Klasse verdeckt oder überschrieben wird, erfolgt die Suche nach der Eigenschaft immer statisch. Der deklarierte (also zur Compilierzeit bekannte) Typ der Variable bestimmt die Interpretation des Eigenschaftsbezeichners. Aus diesem Grund wird nach dem Ausführen des folgenden Codes durch das Lesen oder Schreiben von &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;MyObject.Value&amp;lt;/span&amp;gt; die Methode &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Method1&amp;lt;/span&amp;gt; bzw. &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;Method2&amp;lt;/span&amp;gt; aufgerufen, obwohl &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;MyObject&amp;lt;/span&amp;gt; eine Instanz von &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;TDescendant&amp;lt;/span&amp;gt; enthält. Sie können aber durch eine Typumwandlung in &amp;lt;span class=&amp;quot;codeInline&amp;quot;&amp;gt;TDescendant&amp;lt;/span&amp;gt; auf die Eigenschaften und Zugriffsangaben der abgeleiteten Klasse zugreifen.&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
     TAncestor = class&lt;br /&gt;
       ...&lt;br /&gt;
       property Value: Integer read Method1 write Method2;&lt;br /&gt;
     end;&lt;br /&gt;
 &lt;br /&gt;
     TDescendant = class(TAncestor)&lt;br /&gt;
       ...&lt;br /&gt;
       property Value: Integer read Method3 write Method4;&lt;br /&gt;
     end;&lt;br /&gt;
 &lt;br /&gt;
  var MyObject: TAncestor;&lt;br /&gt;
       ...&lt;br /&gt;
      MyObject := TDescendant.Create;&lt;br /&gt;
&lt;br /&gt;
==Klasseneigenschaften==&lt;br /&gt;
&lt;br /&gt;
Auf Klasseneigenschaften kann ohne Objektreferenz zugegriffen werden. Methoden für den Zugriff auf Klasseneigenschaften müssen als klassenstatisch bzw. als Klassenfelder deklariert sein. Eine Klasseneigenschaft wird mit dem Schlüsselwörtern &#039;&#039;&#039;class property&#039;&#039;&#039; deklariert. Klasseneigenschaften können nicht als &#039;&#039;&#039;published&#039;&#039;&#039; deklariert werden und keine &#039;&#039;&#039;stored&#039;&#039;&#039;- oder &#039;&#039;&#039;default&#039;&#039;&#039;-Wertdefinitionen haben.&lt;br /&gt;
&lt;br /&gt;
Mithilfe einer &#039;&#039;&#039;class var&#039;&#039;&#039;-Deklaration können Sie einen Block von statischen Klassenfeldern innerhalb einer Klassendeklaration erzeugen. Alle nach &#039;&#039;&#039;class var&#039;&#039;&#039; deklarierten Felder haben statische Speicherattribute. Ein &#039;&#039;&#039;class var&#039;&#039;&#039;-Block wird durch Folgendes abgeschlossen:&lt;br /&gt;
&lt;br /&gt;
# Eine weitere &#039;&#039;&#039;class var&#039;&#039;&#039;-Deklaration&lt;br /&gt;
# Eine [[Methoden (Delphi)|Prozedur- oder Funktionsdeklaration (Methodendeklaration)]] (einschließlich Klassenprozeduren und Klassenfunktionen) &lt;br /&gt;
# Eine Eigenschaftsdeklaration (einschließlich Klasseneigenschaften)&lt;br /&gt;
# Eine [[Methoden (Delphi)|Konstruktor- oder Destruktor-Deklaration]]&lt;br /&gt;
# Ein [[Klassen und Objekte (Delphi)|Sichtbarkeitsattribut]] (&#039;&#039;&#039;public&#039;&#039;&#039;, &#039;&#039;&#039;private&#039;&#039;&#039;, &#039;&#039;&#039;protected&#039;&#039;&#039;, &#039;&#039;&#039;published&#039;&#039;&#039;, &#039;&#039;&#039;strict private&#039;&#039;&#039; und &#039;&#039;&#039;strict protected&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
 &lt;br /&gt;
 type&lt;br /&gt;
    TMyClass = class&lt;br /&gt;
      strict private&lt;br /&gt;
        class var         // Felder müssen als Klassenfelder deklariert werden&lt;br /&gt;
           FRed: Integer;&lt;br /&gt;
           FGreen: Integer;&lt;br /&gt;
           FBlue: Integer;&lt;br /&gt;
        public             // Ende des class var-Blocks&lt;br /&gt;
           class property Red: Integer read FRed write FRed;&lt;br /&gt;
           class property Green: Integer read FGreen write FGreen;&lt;br /&gt;
           class property Blue: Integer read FBlue write FBlue;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
Auf die obigen Klasseneigenschaften kann folgendermaßen zugegriffen werden:&lt;br /&gt;
 &lt;br /&gt;
 TMyClass.Red := 0;&lt;br /&gt;
 TMyClass.Blue := 0;&lt;br /&gt;
 TMyClass.Green := 0;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Klassen und Objekte (Delphi)]]&lt;br /&gt;
* [[Felder (Delphi)]]&lt;br /&gt;
* [[Methoden (Delphi)]]&lt;br /&gt;
* [[Ereignisse (Delphi)]]&lt;br /&gt;
* [[Verschachtelte Typdeklarationen]]&lt;br /&gt;
* [[Klassenreferenzen]]&lt;br /&gt;
* [[Exceptions (Delphi)]]&lt;br /&gt;
* [[Überladene Operatoren (Delphi)]]&lt;br /&gt;
* [[Unterstützende Klassen und Records (Delphi)]]&lt;br /&gt;
&lt;br /&gt;
[[Category:{{Delphi}}]]&lt;br /&gt;
[[Category:{{Delphi}}-Sprachreferenz]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Properties (Delphi)]]&lt;br /&gt;
[[fr:Propriétés (Delphi)]]&lt;br /&gt;
[[ja:プロパティ]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215124</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215124"/>
		<updated>2021-03-04T14:06:41Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Operatorüberladung für Klassen */ Added templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. }}&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
{{Note| Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. }}&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. }}&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
{{Note| Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.}}&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. }}&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warning| &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.}}&lt;br /&gt;
&lt;br /&gt;
{{Note| Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. }}&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
{{Note| Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. }}&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215123</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215123"/>
		<updated>2021-03-04T14:06:10Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Das Attribut &amp;quot;Unsafe&amp;quot; */ Added templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. }}&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
{{Note| Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. }}&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. }}&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
{{Note| Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.}}&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. }}&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warning| &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.}}&lt;br /&gt;
&lt;br /&gt;
{{Note| Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. }}&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215122</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215122"/>
		<updated>2021-03-04T14:05:04Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Schwache Referenzen */ Added template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. }}&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
{{Note| Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. }}&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. }}&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
{{Note| Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.}}&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. }}&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Warnung:&#039;&#039;&#039; &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215121</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215121"/>
		<updated>2021-03-04T13:58:35Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Die Methoden Free und DisposeOf unter ARC */ Added Template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. }}&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
{{Note| Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. }}&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. }}&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Warnung:&#039;&#039;&#039; &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215120</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215120"/>
		<updated>2021-03-04T13:57:26Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Änderungen des Programmierstils */ Added templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Note| Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. }}&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
{{Note| Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. }}&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Warnung:&#039;&#039;&#039; &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215119</id>
		<title>Automatische Referenzzählung in mobilen Delphi-Compilern</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Automatische_Referenzz%C3%A4hlung_in_mobilen_Delphi-Compilern&amp;diff=215119"/>
		<updated>2021-03-04T13:49:39Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Automatische Referenzzählung */ Added templates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Gesichtspunkte für geräteübergreifende Delphi-Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
{{Delphi}}-Benutzer sind seit langem mit dem Begriff der automatischen Referenzzählung (ARC, Automatic Reference Counting) vertraut. In der Vergangenheit haben die {{Delphi}}-Desktop-Compiler (DCC32, DCC64, DCCOSX) ARC für Interfaces (in &#039;&#039;&#039;{{Delphi}} 3&#039;&#039;&#039; eingeführt), dynamische Arrays und Strings (&#039;&#039;&#039;AnsiString&#039;&#039;&#039; wurde in &#039;&#039;&#039;{{Delphi}} 2&#039;&#039;&#039; eingeführt) unterstützt. Jetzt wurde für die mobilen {{Delphi}}-Compiler die automatische Referenzzählung auch für Klassen eingeführt. In diesem Zusammenhang wurde auch der Begriff der &#039;&#039;&#039;schwachen Referenz&#039;&#039;&#039; eingeführt, um &amp;quot;Zyklen&amp;quot; gemeinsam mit einem anderen Feature zu verwalten: &#039;&#039;&#039;Operatorüberladung für Klassen&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Eine detaillierte Beschreibung der automatischen Referenzzählung finden Sie unter &#039;&#039;&#039;[https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Automatische Referenzzählung==&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Automatische Referenzzählung&#039;&#039;&#039; ist eine Möglichkeit zur Verwaltung der Objektlebensdauer ohne Freigabe des Objekts, wenn es nicht mehr benötigt wird. Ein gutes Beispiel dafür ist eine lokale Variable, die ein Objekt referenziert, das den Gültigkeitsbereich verlässt. Daran anschließend wird das Objekt automatisch freigegeben. Wie oben erwähnt, hat {{Delphi}} immer schon die Referenzzählung für Strings und durch Variablen vom Typ Interface referenzierte Objekte unterstützt. ARC bietet aber in den mobilen {{Delphi}} -Compilern eine gewisse Flexibilität, um Probleme, wie zirkuläre Referenzen, zu beheben, die mit Variablen vom Typ Interface schwer zu handhaben sind.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer in den neuen mobilen {{Delphi}}-Compilern eingeführter Begriff ist &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039;. Damit werden auch einige Probleme mit zirkulären Referenzen behoben.&lt;br /&gt;
&lt;br /&gt;
Das Speicherverwaltungsschema ist dasselbe für Apps, die für iOS-Geräte oder den iOS-Simulator compiliert werden:&lt;br /&gt;
&lt;br /&gt;
* DCCIOSARM (der {{Delphi}}-Compiler für das 32-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOSARM64 (der {{Delphi}}-Compiler für das 64-Bit-iOS-Gerät) verfügt standardmäßig über ARC (Automatic Reference Counting).&lt;br /&gt;
* DCCIOS32 (der {{Delphi}}-Compiler für den iOS-Simulator) aktiviert ARC auch, obwohl DCCIOS32 auf der herkömmlichen Compiler-Architektur basiert. &lt;br /&gt;
&lt;br /&gt;
{{Note| Diese neuen Features erscheinen im Quellcode von {{Variables|Product}} ausschließlich in den konditionalen &amp;lt;code&amp;gt;{$AUTOREFCOUNT}&amp;lt;/code&amp;gt;-Blöcken in der RTL (z. B. in &#039;&#039;System.pas&#039;&#039;).  }}&lt;br /&gt;
&lt;br /&gt;
==Änderungen des Programmierstils==&lt;br /&gt;
&lt;br /&gt;
Da die neuen mobilen Compiler die automatische Referenzzählung unterstützen, kann beim Verweisen auf temporäre Objekte in einer Methode der Code deutlich vereinfacht werden. Die Speicherverwaltung wird vollständig ignoriert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im obigen Beispiel wird der Destruktor für das Objekt aufgerufen, wenn das Programm die &#039;&#039;&#039;end&#039;&#039;&#039;-Anweisung erreicht, das heißt, wenn die Variable &amp;lt;code&amp;gt;MyObj&amp;lt;/code&amp;gt; den Gültigkeitsbereich verlässt.&lt;br /&gt;
&lt;br /&gt;
Die Verwendung des Objekts kann auch vor dem Ende der Methode beendet werden. Dies kann durch Setzen der Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; erreicht werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.SetNil;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  MyObj.DoSomething (False); // True =&amp;gt; raise&lt;br /&gt;
  MyObj := nil;	&lt;br /&gt;
  // do something else&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Fall wird das Objekt vor dem Ende der Methode freigegeben und zwar genau dann, wenn die Variable auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt wird. Falls die &amp;lt;code&amp;gt;DoSomething&amp;lt;/code&amp;gt;-Prozedur eine Exception auslöst, wird die &#039;&#039;&#039;nil&#039;&#039;&#039;-Zuweisungsanweisung übersprungen. Wird die Methode schließlich beendet, wird auch das Objekt freigegeben.&lt;br /&gt;
&lt;br /&gt;
Da sich die Lebensdauer des Objekts nach dem Programmfluss richtet, können Sie den Referenzzähler eines Objekts (nur auf Plattformen mit Referenzzählung) mit der neuen Eigenschaft RefCount abfragen:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
public&lt;br /&gt;
    property RefCount: Integer read FRefCount;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das Abfragen des Referenzzählers eines Objekts wird nicht empfohlen und sollte im Allgemeinen nicht verwendet werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Geschwindigkeit von ineinandergreifenden Vorgängen===&lt;br /&gt;
&lt;br /&gt;
Das Inkrementieren und Dekrementieren des Referenzzählers eines Objekts wird unter Verwendung von Thread-sicher Operationen durchgeführt, damit der Member der Referenzzählerinstanz Thread-sicher ist. Das bedeutet, dass die Referenzzähler-Instanzvariable korrekt durch &#039;&#039;&#039;Speicherbarrieren&#039;&#039;&#039; abgeschirmt ist, damit die Änderung von allen Threads sofort beachtet wird und sie keinen &#039;&#039;&#039;alten&#039;&#039;&#039; Wert ändern können.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Der ARC-Mechanismus schützt nicht vor Racebedingungen und Deadlocks. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ARC und die Direktive {$AUTOREFCOUNT}===&lt;br /&gt;
&lt;br /&gt;
Mit der Direktive &amp;lt;code&amp;gt;{$IFDEF AUTOREFCOUNT}&amp;lt;/code&amp;gt; kann unter Umständen der beste Code für beide Szenarien erzielt werden: ARC und traditionell. &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; definiert Code, der die automatische Referenzzählung verwendet, wie z. B. Code für die mobilen {{Delphi}}-Compiler. Diese Direktive ist sehr wichtig und unterscheidet sich von &amp;lt;code&amp;gt;{$IFDEF NEXTGEN}&amp;lt;/code&amp;gt; (der Direktive, die die neuen Sprach-Features der mobilen Compiler definiert).  &amp;lt;code&amp;gt;AUTOREFCOUNT&amp;lt;/code&amp;gt; könnte zukünftig nützlich werden, für den Fall, dass ARC auch für die {{Delphi}}-Desktop-Compiler implementiert wird.&lt;br /&gt;
&lt;br /&gt;
==Die Methoden [[lib_de:System.TObject.Free|Free]] und [[lib_de:System.TObject.DisposeOf|DisposeOf]] unter ARC==&lt;br /&gt;
&lt;br /&gt;
Bei Klassen sind {{Delphi}}-Entwickler ein anderes Programmiermuster auf Basis der Methode &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und geschützt durch den &amp;lt;code&amp;gt;try-finally&amp;lt;/code&amp;gt;-Block gewöhnt. &lt;br /&gt;
&lt;br /&gt;
Zum Beispiel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMySimpleClass.TryFinally;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.Free;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei den {{Delphi}}-Desktop-Compilern ist &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; eine Methode von &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt;, die überprüft, ob die aktuelle Referenz nicht nil ist, und in diesem Fall den &amp;lt;code&amp;gt;Destroy&amp;lt;/code&amp;gt;-Destruktor aufruft, der das Objekt nach Ausführung des entsprechenden Destruktorcodes aus dem Speicher entfernt.&lt;br /&gt;
&lt;br /&gt;
In den neuen mobilen {{Delphi}}-Compilern wird der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; durch die Zuweisung von &#039;&#039;&#039;nil&#039;&#039;&#039; zu der Variable ersetzt. Falls es sich dabei um die letzte Referenz auf das Objekt handelt, wird es weiterhin nach dem Aufruf des Destruktors aus dem Speicher entfernt. Falls es noch bestehende Referenzen gibt, passiert nichts (außer einer Verringerung des Referenzzählers).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
FreeAndNil (MyObj);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso setzt ein Aufruf wie der obige das Objekt auf &#039;&#039;&#039;nil&#039;&#039;&#039; und löst wieder die Objektfreigabe nur dann aus, wenn keine anderen Variablen das Objekt referenzieren. In den meisten Fällen ist das korrekt, weil keine Objekte freigegeben werden sollen, die in anderen Programmteilen verwendet werden. Andererseits gibt es Szenarien, in denen der Destruktorcode sofort ausgeführt werden muss, unabhängig davon, ob andere ausstehende Referenzen auf das Objekt vorhanden sind. Damit Entwickler die Ausführung des Destruktors (ohne Freigabe des eigentlichen Objekts aus dem Speicher) erzwingen können, führen die neuen Compiler ein Freigabemuster ein:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
MyObject.DisposeOf;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf führt den Destruktorcode auch dann aus, wenn ausstehende Referenzen vorhanden sind.  Das Objekt wird hierbei in einen speziellen Zustand versetzt, damit der Destruktor bei weiteren Freigabeoperationen oder wenn der Referenzzähler null erreicht, und Speicher tatsächlich freigegeben wird, nicht nochmals aufgerufen wird. Dieser &#039;&#039;&#039;freigegebene&#039;&#039;&#039; Zustand (oder &#039;&#039;&#039;Zombie&#039;&#039;&#039;-Zustand) ist ziemlich wichtig, und Sie können diesen Objektzustand mit der Eigenschaft &amp;lt;code&amp;gt;[[lib_de:System.TObject.Disposed|Disposed]]&amp;lt;/code&amp;gt; abfragen. &lt;br /&gt;
&lt;br /&gt;
Wie weiter oben bereits erwähnt, funktionieren die klassischen &#039;&#039;&#039;try-finally&#039;&#039;&#039;-Blöcke, die mit den {{Delphi}}-Desktop-Compiler verwendet werden, auch mit den neuen Compilern, auch wenn sie nicht erforderlich sind.&lt;br /&gt;
In den meisten Fällen sollten Sie aber den &#039;&#039;&#039;dispose&#039;&#039;&#039;-Programmierstil verwenden (außer Sie möchten den Code für frühere Versionen von {{Delphi}} compilieren).&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel wird derselbe Effekt wie mit dem klassischen Compiler erzielt, weil &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; Free aufruft. Der Code führt wie erwartet den Destruktor aus (zur selben Zeit wie der klassische Compiler, aber der Speicher wird vom ARC-Mechanismus verwaltet).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  MyObj: TMySimpleClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyObj := TMySimpleClass.Create;&lt;br /&gt;
  try&lt;br /&gt;
    MyObj.DoSomething;&lt;br /&gt;
  finally&lt;br /&gt;
    MyObj.DisposeOf;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Die Speicherung des Disposed-Flags wird durch ein Bit im Feld &amp;lt;code&amp;gt;FRefCount&amp;lt;/code&amp;gt; erreicht, unter Berücksichtigung, dass die Obergrenze der Referenzen für ein Objekt bei 2&amp;lt;sup&amp;gt;30&amp;lt;/sup&amp;gt; liegt. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Erstellungs- und Freigabemethoden für TObject unter ARC==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Abschnitte enthalten eine Übersicht über die Methoden in der Klasse &amp;lt;code&amp;gt;TObject&amp;lt;/code&amp;gt; in Bezug auf Erstellung und Freigabe.&lt;br /&gt;
&lt;br /&gt;
Die Unterschiede zwischen &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; können auch unter Berücksichtigung des Zwecks betrachtet werden. &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; wird verwendet, um eine bestimmte Referenz von einer Instanz zu trennen. Dabei ist eine Freigabe des Objekts oder von Speicher nicht impliziert. Im Gegensatz dazu teilt der Programmierer mit &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; der Instanz explizit mit, &amp;quot;sich selbst zu bereinigen&amp;quot;. Eine Speicherfreigabe ist dabei nicht notwendigerweise impliziert, &amp;lt;code&amp;gt;DisposeOf&amp;lt;/code&amp;gt; führt eine explizite &amp;quot;Vorbereinigung&amp;quot; der Instanz durch. Anschließend ist die Instanz von der normalen Referenzzählungssemantik abhängig, die die Instanz dann schließlich freigeben kann.&lt;br /&gt;
&lt;br /&gt;
==Schwache Referenzen==&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Konzept für ARC ist die Rolle von &#039;&#039;&#039;schwachen Referenzen&#039;&#039;&#039;. Sie erstellen schwache Referenzen, indem Sie Referenzen mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; versehen. Angenommen, zwei Objekte referenzieren sich gegenseitig über ein Feld, und eine externe Variable referenziert das erste Objekt. Der Referenzzähler des ersten Objekts ist 2 (die externe Variable und das zweite Objekt) und der Referenzzähler des zweiten Objekts ist 1. Wenn die externe Variable den Gültigkeitsbereich verlässt, haben beide Objekte einen Referenzzähler von 1, und sie verbleiben unendlich im Speicher.&lt;br /&gt;
&lt;br /&gt;
Um diese Situation und viele ähnlichen Szenarien zu lösen, wird eine schwache Referenz verwendet, um die zirkulären Referenzen aufzuheben, wenn die letzte externe Referenz den Gültigkeitsbereich verlässt. &lt;br /&gt;
&lt;br /&gt;
Eine &#039;&#039;&#039;schwache Referenz&#039;&#039;&#039; ist eine Referenz auf ein Objekt, dessen Referenzzähler nicht erhöht wird. Eine schwache Referenz wird mit dem Attribut &amp;lt;code&amp;gt;[weak]&amp;lt;/code&amp;gt; deklariert, das von den mobilen {{Delphi}}-Compilern unterstützt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn in dem vorherigen Szenario die Referenz von dem zweiten Objekt auf das erste Objekt schwach ist, werden – sobald die externe Variable den Gültigkeitsbereich verlässt – beide Objekte freigegeben. Hier ist ein Beispiel für diese Situation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TMyComplexClass = class;&lt;br /&gt;
&lt;br /&gt;
  TMySimpleClass = class&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwnedBy: TMyComplexClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    procedure DoSomething(bRaise: Boolean = False);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  TMyComplexClass = class&lt;br /&gt;
  private&lt;br /&gt;
    fSimple: TMySimpleClass;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create();&lt;br /&gt;
    destructor Destroy (); override;&lt;br /&gt;
    class procedure CreateOnly;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im folgenden Codefragment erstellt der Konstruktor der komplexen Klasse ein Objekt der anderen Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
constructor TMyComplexClass.Create;&lt;br /&gt;
begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  FSimple := TMySimpleClass.Create;&lt;br /&gt;
  FSimple.FOwnedBy := self;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil das Feld &amp;lt;code&amp;gt;FOwnedBy&amp;lt;/code&amp;gt; eine schwache Referenz ist, wird der Referenzzähler des Objekts, auf das es verweist – in diesem Fall auf das aktuelle Objekt (&#039;&#039;&#039;self&#039;&#039;&#039;) – nicht erhöht. &lt;br /&gt;
&lt;br /&gt;
Daher können Sie für diese Klassenstruktur Folgendes schreiben:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
class procedure TMyComplexClass.CreateOnly;&lt;br /&gt;
var&lt;br /&gt;
  MyComplex: TMyComplexClass;&lt;br /&gt;
begin&lt;br /&gt;
  MyComplex := TMyComplexClass.Create;&lt;br /&gt;
  MyComplex.fSimple.DoSomething;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Code verursacht kein Speicherleck, vorausgesetzt, dass die schwache Referenz richtig angewendet wird.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres Beispiel für die Verwendung von schwachen Referenzen ist dieses Codefragment aus der {{Delphi}}-RTL, das Teil der Klassendeklaration von [[lib_de:System.Classes.TComponent|TComponent]] ist:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TComponent = class(TPersistent, IInterface,&lt;br /&gt;
    IInterfaceComponentReference)&lt;br /&gt;
  private&lt;br /&gt;
    [Weak] FOwner: TComponent;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn Sie das Attribut &#039;&#039;&#039;weak&#039;&#039;&#039; in Code angeben, der von einem der {{Delphi}}-Desktop-Compiler compiliert wird, dann wird das Attribut ignoriert. Für DCC32 müssen Sie sicherstellen, dass Sie den korrekten Code im Destruktor eines &amp;quot;Eigentümer&amp;quot;-Objekts angeben, damit auch das Objekt, das der Eigentümer &amp;quot;besitzt&amp;quot;, freigegeben wird. Der Aufruf von &amp;lt;code&amp;gt;Free&amp;lt;/code&amp;gt; ist zulässig, obwohl damit ein anderer Effekt als in den mobilen {{Delphi}}-Compilern erreicht wird. Das Verhalten ist in den meisten Fällen korrekt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Wenn für eine Instanz der Speicher freigegeben wird, werden alle aktiven &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Referenzen auf &#039;&#039;&#039;nil&#039;&#039;&#039; gesetzt. Genau wie bei &#039;&#039;&#039;starken&#039;&#039;&#039; (normalen) Referenzen kann eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable nur &#039;&#039;&#039;nil&#039;&#039;&#039; sein oder eine gültige Instanz referenzieren. Das ist der Hauptgrund, warum eine &#039;&#039;&#039;schwache&#039;&#039;&#039; Referenz vor dem Testen auf &#039;&#039;&#039;nil&#039;&#039;&#039; und dem Dereferenzieren einer &#039;&#039;&#039;starken&#039;&#039;&#039; Referenz zugewiesen werden soll. Durch Zuweisung zu einer starken Referenz kann die Instanz nicht vorzeitig freigegeben werden.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
var&lt;br /&gt;
  O: TComponent;// a strong reference&lt;br /&gt;
begin&lt;br /&gt;
  O := FOwner;  // assigning a weak reference to a strong reference&lt;br /&gt;
  if O &amp;lt;&amp;gt; nil then&lt;br /&gt;
    O.&amp;lt;method&amp;gt;;// safe to dereference&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[weak]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[weak]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[weak]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Das Attribut &amp;quot;Unsafe&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie die folgende Syntax, um das Attribut &#039;&#039;&#039;unsafe&#039;&#039;&#039; für eine Funktion festzulegen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
[Result: Unsafe] function ReturnUnsafe: TObject;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Warnung:&#039;&#039;&#039; &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; kann auch für Variablen (Member) und Parameter verwendet werden. Es sollte außerhalb der Unit [[lib_de:System|System]] nur in sehr seltenen Situationen verwendet werden. Es gilt als gefährlich, und die Verwendung von [Unsafe] wird nicht empfohlen, weil keine Referenzzählung generiert wird.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Eine &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039;-Variable kann nur einem &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden, der auch mit &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; gekennzeichnet ist. Eine normale &#039;&#039;&#039;starke&#039;&#039;&#039; Referenz kann keinem &#039;&#039;&#039;[Unsafe]&#039;&#039;&#039; &#039;&#039;&#039;var&#039;&#039;&#039;- oder &#039;&#039;&#039;out&#039;&#039;&#039;-Parameter übergeben werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Operatorüberladung für Klassen==&lt;br /&gt;
&lt;br /&gt;
Ein interessanter Nebeneffekt der ARC-Speicherverwaltung ist, dass der Compiler die Lebensdauer temporärer von Funktionen zurückgegebener Objekte handhaben kann. Einen speziellen Fall stellen temporäre von Operatoren zurückgegebene Objekte dar. Ein ganz neues Feature der neuen {{Delphi}}-Compiler ist die Möglichkeit, Operatoren für Klassen zu definieren, mit derselben Syntax und demselben Modell, das für Records seit {{Delphi}} 2006 verfügbar ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Das folgende Codebeispiel funktioniert für die mobilen {{Delphi}}-Compiler (iOS), kann aber nicht von den {{Delphi}}-Desktop-Compilern compiliert werden. &amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Beispiel dient die folgende einfache Klasse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TNumber = class&lt;br /&gt;
  private&lt;br /&gt;
    FValue: Integer;&lt;br /&gt;
    procedure SetValue(const Value: Integer);&lt;br /&gt;
  public&lt;br /&gt;
    property Value: Integer read FValue write SetValue;&lt;br /&gt;
    constructor Create(Value: Integer);&lt;br /&gt;
    function ToString: string; override;&lt;br /&gt;
    class operator Add (a, b: TNumber): TNumber;&lt;br /&gt;
    class operator Implicit (n: TNumber): Integer;&lt;br /&gt;
    class operator Implicit(n: Integer): TNumber;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
constructor TNumber.Create(Value: Integer); begin&lt;br /&gt;
  inherited Create;&lt;br /&gt;
  Self.Value := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Add(a, b: TNumber): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(a.Value + b.Value); end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: TNumber): Integer; begin&lt;br /&gt;
  Result := n.Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
class operator TNumber.Implicit (n: Integer): TNumber; begin&lt;br /&gt;
  Result := TNumber.Create(n);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure TNumber.SetValue(const Value: Integer); begin&lt;br /&gt;
  FValue := Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function TNumber.ToString: string;&lt;br /&gt;
begin&lt;br /&gt;
  Result := IntToStr(Value);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
procedure Test;&lt;br /&gt;
var&lt;br /&gt;
  a, b, c: TNumber;&lt;br /&gt;
begin&lt;br /&gt;
  a := 10;&lt;br /&gt;
  b := 20;&lt;br /&gt;
  c := a + b;&lt;br /&gt;
  Writeln(c.ToString);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Automatische Referenzzählung in C++|Automatische Referenzzählung in C++]]&lt;br /&gt;
* [[Mobile iOS-Anwendungsentwicklung|Mobile iOS-Anwendungsentwicklung]]&lt;br /&gt;
* [[DCCIOS32.EXE: Der Delphi-Compiler für den iOS-Simulator|DCCIOS32: Der Delphi-Compiler für den iOS-Simulator]]&lt;br /&gt;
* [[DCCIOSARM.EXE: Der Delphi-Compiler für 32-Bit-iOS-Geräte|DCCIOSARM: Der Delphi-Compiler für 32-Bit-iOS-Geräte]]&lt;br /&gt;
* [[DCCIOSARM64.EXE: Der Delphi-Compiler für 64-Bit-iOS-Geräte|DCCIOSARM64, Der Delphi-Compiler für 64-Bit-iOS-Geräte]]&lt;br /&gt;
* [https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html Release Notes for ARC (Apple Computers)]&lt;br /&gt;
* [[Referenzzählung einsetzen|Referenzzählung einsetzen]] (über Interfaces mit {{Delphi}}-Desktop-Compilern)&lt;br /&gt;
&lt;br /&gt;
===Codebeispiel===&lt;br /&gt;
&lt;br /&gt;
* [[samp_en:AutomaticReferenceCounting (Delphi)|AutomaticReferenceCounting ({{Delphi}})]]&lt;br /&gt;
&lt;br /&gt;
{{DEFAULTSORT:Automatische Referenzzahlung in mobilen Delphi-Compilern}}&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:XE4]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Automatic Reference Counting in Delphi Mobile Compilers]]&lt;br /&gt;
[[fr:Comptage automatique des références dans les compilateurs mobiles Delphi]]&lt;br /&gt;
[[ja:Delphi モバイル コンパイラでの自動参照カウント]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Debugger_auf_einem_externen_Computer_installieren&amp;diff=215101</id>
		<title>Debugger auf einem externen Computer installieren</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Debugger_auf_einem_externen_Computer_installieren&amp;diff=215101"/>
		<updated>2021-01-05T23:24:59Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Remote-Debugger-Dateien werden auf dem externen Computer installiert */ RS-98408&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Remote-Debuggen - Alte Verfahren|Remote-Debugging - Alte Verfahren}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; In diesem Thema wird die Installation des alten Remote-Debuggers beschrieben.&amp;lt;br /&amp;gt; &lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Obwohl die herkömmliche Lösung für das Remote-Debugging weiterhin unterstützt wird, sollten Sie die neue [[Debuggen von geräteübergreifenden Anwendungen|Lösung für Remote- und geräteübergreifendes Debugging]] verwenden. Damit können Sie:&lt;br /&gt;
* Mit dem integrierten Debugger Remote- und geräteübergreifende Anwendungen debuggen.&lt;br /&gt;
* Mit dem [[Bereitstellungs-Manager|Bereitstellungs-Manager]] Ihre Anwendungen konfigurieren und bereitstellen.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Remote-Debugger-Dateien werden auf dem externen Computer installiert==&lt;br /&gt;
&lt;br /&gt;
Auf einem Windows-PC werden beim [[PAServer: Die Platform Assistant Server-Anwendung|Installieren des &#039;&#039;&#039;Platform Assistant&#039;&#039;&#039;]] die Remote-Debugger-Dateien standardmäßig in {{Path|{{InstallPath}}\PAServer}} installiert. Sie können aber auch ein anderes Installationsverzeichnis auswählen. Wenn Sie den &amp;quot;Platform Assistant&amp;quot; nicht installieren, müssen Sie allerdings die folgenden Remote-Debugger-Dateien auf den Remote-Computer kopieren:&lt;br /&gt;
&lt;br /&gt;
* {{Path|rmtdbg{{PackageVersion}}.exe}}&lt;br /&gt;
* {{Path|bccide.dll}}&lt;br /&gt;
* {{Path|bordbk{{PackageVersion}}.dll}}&lt;br /&gt;
* {{Path|bordbk{{PackageVersion}}N.dll}}&lt;br /&gt;
* {{Path|comp32x.dll}}&lt;br /&gt;
* {{Path|dcc32{{PackageVersion}}.dll}} für ein Win32-System&lt;br /&gt;
* {{Path|dcc64{{PackageVersion}}.dll}} für ein Win64-System&lt;br /&gt;
* {{Path|dccosx{{PackageVersion}}.dll}} für ein OS X-System&lt;br /&gt;
&lt;br /&gt;
:&lt;br /&gt;
::&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Auf dem Entwicklungs-PC werden die Remote-Debugger-Dateien in {{Path|{{InstallPath}}\bin}} bereitgestellt.&lt;br /&gt;
&lt;br /&gt;
==So registrieren Sie den Remote-Debugger:==&lt;br /&gt;
&lt;br /&gt;
Registrieren Sie auf dem Remote-Computer die Dateien {{Path|bordbk{{PackageVersion}}.dll}} und {{Path|bordbk{{PackageVersion}}.dll}} durch Ausführen des Registrierungs-Tools {{Path|regsvr32.exe}}.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unter Windows 7 geben Sie beispielsweise an der Eingabeaufforderung {{Code|C:\Windows\System32\regsvr32.exe bordbk{{PackageVersion}}.dll}} und dann&lt;br /&gt;
&lt;br /&gt;
 C:\Windows\System32\regsvr32.exe bordbk{{PackageVersion}}.dll&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[Überblick zum externen Debugger|Überblick zum externen Debugger]]&lt;br /&gt;
* [[Verbindung für das externe Debuggen einrichten|Verbindung für das externe Debuggen einrichten]]&lt;br /&gt;
* [[Dateien für das externe Debuggen vorbereiten|Dateien für das externe Debuggen vorbereiten]]&lt;br /&gt;
* [[Debuggen von geräteübergreifenden Anwendungen|Debuggen von geräteübergreifenden Anwendungen (Neue Remote-Debugging-Lösung)]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Mit RAD Studio arbeiten]]&lt;br /&gt;
[[Category:Delphi]]&lt;br /&gt;
[[Category:C++]]&lt;br /&gt;
&lt;br /&gt;
[[en:Installing a Debugger on a Remote Machine]]&lt;br /&gt;
[[fr:Installation d&#039;un débogueur sur une machine distante]]&lt;br /&gt;
[[ja:リモート マシンへデバッガをインストールする]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
	<entry>
		<id>https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Verwenden_eines_HTTP-Clients&amp;diff=215097</id>
		<title>Verwenden eines HTTP-Clients</title>
		<link rel="alternate" type="text/html" href="https://docwiki.embarcadero.com/RADStudio/Rio/d/index.php?title=Verwenden_eines_HTTP-Clients&amp;diff=215097"/>
		<updated>2020-12-10T18:41:50Z</updated>

		<summary type="html">&lt;p&gt;Alejandra.Barrientos: /* Behandeln der HTTP-Basiszugriffsauthentifizierung */ RS-102658&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Parent|Verwenden der RTL in geräteübergreifenden Anwendungen}}&lt;br /&gt;
&lt;br /&gt;
Die RTL enthält zwei Komponenten, mit denen Sie HTTP-Anforderungen an Server senden und deren Antworten verwalten können:&lt;br /&gt;
&lt;br /&gt;
*  [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]]&lt;br /&gt;
* [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]]&lt;br /&gt;
&lt;br /&gt;
: {{Note| Alternativ können Sie eine Instanz von [[lib_de:System.Net.HttpClient.THTTPClient|THTTPClient]] zum Verwalten Ihrer HTTP-Anforderungen verwenden.}}&lt;br /&gt;
&lt;br /&gt;
==Konfigurieren Ihre Anwendung beim Entwurf==&lt;br /&gt;
&lt;br /&gt;
===Erstellen eines HTTP-Clients===&lt;br /&gt;
&lt;br /&gt;
Um einen HTTP-Client zu erstellen, mit dem Sie HTTP-Anforderungen senden können, ziehen Sie eine [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]]-Komponente aus der &#039;&#039;&#039;[[Tool-Palette|Tool-Palette]]&#039;&#039;&#039; in ein Formular oder ein Datenmodul Ihrer Anwendung. Für die Komponente [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]] ist keine Anfangskonfiguration erforderlich.&lt;br /&gt;
&lt;br /&gt;
===Erstellen und Konfigurieren von HTTP-Anforderungen===&lt;br /&gt;
&lt;br /&gt;
Sie müssen auch mindestens eine [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]]-Komponente in Ihr Formular oder Datenmodul aufnehmen.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie die neue HTTP-Anforderungs-Komponente eingefügt haben, doppelklicken Sie im &#039;&#039;&#039;[[Objektinspektor|Objektinspektor]]&#039;&#039;&#039; auf deren Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Client|Client]], damit der Wert auf die zuvor hinzugefügte HTTP-Client-Komponente gesetzt wird.&lt;br /&gt;
&lt;br /&gt;
Sie können eine beliebige Anzahl von Anforderungs-Komponenten verwenden. Wenn Sie mehrere unterschiedliche HTTP-Anforderungen senden müssen, wäre das geeignetere Vorgehen jedoch, nur eine HTTP-Anforderungs-Komponente zu verwenden und diese zur Laufzeit für jede Anforderung neu zu konfigurieren.&lt;br /&gt;
&lt;br /&gt;
==Senden einer Anforderung und Behandeln der Antwort==&lt;br /&gt;
&lt;br /&gt;
===Senden einer HTTP-Anforderung===&lt;br /&gt;
&lt;br /&gt;
Um eine HTTP-Anforderung zu senden, müssen Sie mindestens Folgendes angeben:&lt;br /&gt;
&lt;br /&gt;
* [[Wikipedia:Hypertext Transfer Protocol#Request methods|HTTP-Anforderungsmethoden]]&lt;br /&gt;
* Einen Ressourcen-URL&lt;br /&gt;
&lt;br /&gt;
Die HTTP-Anforderungsmethode bestimmt die Aktion, die der Server für die Ressource an dem angegebenen URL ausführen soll, z. B. Senden der Daten der Ressource oder Aktualisieren der Ressource mit Daten aus der Anforderung.&lt;br /&gt;
&lt;br /&gt;
Wie eine HTTP-Anforderung mit einer [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest|TNetHTTPRequest]]-Komponente gesendet wird, hängt von der HTTP-Anforderungsmethode ab, die Sie verwenden möchten.&lt;br /&gt;
&lt;br /&gt;
: {{Note| Funktionen, die eine Anforderung senden, entweder [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|Execute]] oder methodenspezifische Funktionen, sind alle blockierend. Das heißt, diese Funktionen kehren erst zurück, wenn eine Antwort vom Server vorliegt. Siehe [[#Verfolgen des Fortschritts beim Herunterladen der Antwortdaten|Verfolgen des Fortschritts beim Herunterladen der Antwortdaten]] weiter unten.}}&lt;br /&gt;
&lt;br /&gt;
====Senden einer HTTP-Anforderung mit den HTTP-Anforderungsmethoden DELETE, GET, HEAD, OPTIONS oder TRACE====&lt;br /&gt;
&lt;br /&gt;
Die folgenden HTTP-Anforderungsmethoden benötigen als Eingabedaten nur den Zielressourcen-URL:&lt;br /&gt;
&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7 DELETE (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 GET (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 HEAD (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2 OPTIONS (EN)]&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8 TRACE (EN)]&lt;br /&gt;
&lt;br /&gt;
Konfigurieren Sie Ihre Anforderung zuerst beim Entwurf, um eine HTTP-Anforderung mit einer dieser HTTP-Anforderungsmethoden zu senden:&lt;br /&gt;
&lt;br /&gt;
# Konfigurieren Sie die Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.URL|URL]] mit dem URL der Zielressource.&lt;br /&gt;
# Konfigurieren Sie die Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.MethodString|MethodString]] mit dem Namen der HTTP-Anforderungsmethode, die Sie verwenden möchten.&lt;br /&gt;
#: {{Note| Namen von HTTP-Anforderungsmethoden [http://tools.ietf.org/html/rfc7230 berücksichtigen die Groß-/Kleinschreibung (EN)].}}&lt;br /&gt;
&lt;br /&gt;
Rufen Sie dann &#039;&#039;&#039;[[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|Execute]]&#039;&#039;&#039; auf, um Ihre Anforderung zu senden.&lt;br /&gt;
&lt;br /&gt;
====Senden einer HTTP-Anforderung mit den HTTP-Anforderungsmethoden MERGE, PATCH oder PUT====&lt;br /&gt;
&lt;br /&gt;
Die folgenden HTTP-Anforderungsmethoden benötigen außer dem Zielressourcen-URL Eingabedaten:&lt;br /&gt;
&lt;br /&gt;
* [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 PUT (EN)]&lt;br /&gt;
* [http://tools.ietf.org/html/rfc5789 PATCH (EN)]&lt;br /&gt;
* [http://www.odata.org/documentation/odata-version-2-0/operations/#Operations MERGE (EN)]&lt;br /&gt;
&lt;br /&gt;
Um eine HTTP-Anforderung mit einer dieser HTTP-Anforderungsmethoden zu senden, rufen Sie die zugehörige Funktion auf (siehe die folgenden Tabelle). Geben Sie in Ihrem Aufruf den URL der Zielressource als erstes Argument und eine Instanz von [[lib_de:System.Classes.TStream|TStream]] als zweites Argument an.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! HTTP-Anforderungsmethode&lt;br /&gt;
! TNetHTTPRequest-Funktion&lt;br /&gt;
|-&lt;br /&gt;
| PUT&lt;br /&gt;
| [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Put|Put]]&lt;br /&gt;
|-&lt;br /&gt;
| PATCH&lt;br /&gt;
| [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Patch|Patch]]&lt;br /&gt;
|-&lt;br /&gt;
| MERGE&lt;br /&gt;
| [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Merge|Merge]]&lt;br /&gt;
|-&lt;br /&gt;
| PATCH über PUT*&lt;br /&gt;
| [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.PatchAlternative|PatchAlternative]]&lt;br /&gt;
|-&lt;br /&gt;
| MERGE über PUT*&lt;br /&gt;
| [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.MergeAlternative|MergeAlternative]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt; Einige HTTP-Proxies unterstützen die neuesten Standard-HTTP-Anforderungsmethoden (wie PATCH) oder Nicht-Standard-HTTP-Anforderungsmethoden (wie MERGE) nicht. In diesen Fällen können Sie die HTTP-Anforderungsmethoden über andere HTTP-Anforderungsmethoden tarnen. Dazu müssen in der Anforderung Header enthalten sein, die die gewünschte HTTP-Anforderungsmethode angeben.&lt;br /&gt;
&lt;br /&gt;
====Senden einer HTTP-Anforderung mit der HTTP-Anforderungsmethode POST====&lt;br /&gt;
&lt;br /&gt;
Die HTTP-Anforderungsmethode [http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 POST (EN)] benötigt außer dem Zielressourcen-URL Eingabedaten.&lt;br /&gt;
&lt;br /&gt;
Um eine HTTP-Anforderung mit der HTTP-Anforderungsmethode POST zu senden, rufen Sie [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Post|Post]] auf. In Ihrem Aufruf müssen Sie den URL der Zielressource als erstes Argument angeben. Die anderen Argumente hängen davon ab, wie Sie die Eingabedaten für Ihre Anforderung zur Verfügung stellen möchten:&lt;br /&gt;
&lt;br /&gt;
* Um den Inhalt einer lokalen Datei zu senden, geben Sie den lokalen Pfad zu dieser Datei als zweites Argument Ihres Aufrufs an.&lt;br /&gt;
* Um den Inhalt eines Streams zu senden, geben Sie Ihre Instanz von [[lib_de:System.Classes.TStream|TStream]] als zweites Argument Ihres Aufrufs an.&lt;br /&gt;
* Um Formulardaten zu senden, die entsprechend dem [http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 HTML 4-Standard (EN)] als [[Wikipedia:MIME#Multipart messages|mehrteilige MIME-Nachricht]] codiert sind, geben Sie Ihre Instanz von [[lib_de:System.Net.Mime.TMultipartFormData|TMultipartFormData]] als zweites Argument Ihres Aufrufs an.&lt;br /&gt;
* Um den Inhalt einer String-Liste zu senden, geben Sie Ihre Instanz von [[lib_de:System.Classes.TStrings|TStrings]] als zweites Argument Ihres Aufrufs an, und falls Ihre Strings nicht in UTF-8 codiert sind, geben Sie eine Instanz von [[lib_de:System.SysUtils.TEncoding|TEncoding]] als viertes Argument an. Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPRequest1.Post(&#039;http://www.example.com/rest/items&#039;, String1, nil, TEncoding.Default);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPRequest1-&amp;gt;Post(&amp;quot;http://www.example.com/rest/items&amp;quot;, String1, NULL, TEncoding::Default);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behandeln einer HTTP-Antwort===&lt;br /&gt;
&lt;br /&gt;
Wenn der Zielserver eine Antwort auf Ihre Anforderung sendet, wird das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] Ihrer HTTP-Anforderungs-Komponente ausgelöst. Definieren Sie eine [[Ereignisbehandlungsroutinen|Ereignisbehandlungsroutine]] für dieses Ereignis, um die Daten aus der Serverantwort zu lesen. Wenn während Ihrer Anforderung ein Fehler auftritt, wird stattdessen das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestError|OnRequestError]] Ihrer HTTP-Anforderungs-Komponente ausgelöst.&lt;br /&gt;
&lt;br /&gt;
Die Ereignisbehandlungsroutine von [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] erhält zwei Parameter:&lt;br /&gt;
&lt;br /&gt;
* {{Arg|Sender}} ist Ihre HTTP-Anforderungs-Komponente.&lt;br /&gt;
* {{Arg|AResponse}} ist ein Objekt, das das Interface [[lib_de:System.Net.HttpClient.IHTTPResponse|IHTTPResponse]] implementiert.&lt;br /&gt;
&lt;br /&gt;
Sie können alle Antwortdaten aus {{Arg|AResponse}} abrufen:&lt;br /&gt;
&lt;br /&gt;
* [[lib_de:System.Net.HttpClient.IHTTPResponse.Version|Version]] gibt die Version des HTTP-Protokolls an, das der Server verwendet.&lt;br /&gt;
* [[lib_de:System.Net.HttpClient.IHTTPResponse.StatusCode|StatusCode]] enthält den [[Wikipedia:List of HTTP status codes|Statuscode]] der Antwort, und [[lib_de:System.Net.HttpClient.IHTTPResponse.StatusText|StatusText]] enthält einen lesbaren Text, der den Status beschreibt, wie z. B. &amp;quot;OK&amp;quot; für den StatusCode 200.&lt;br /&gt;
* [[lib_de:System.Net.URLClient.IURLResponse.ContentAsString|ContentAsString]] enthält den Rumpf der Antwort als String. Sie können auch die Rohantwortdaten (einschließlich der Header und des Rumpfs) als Stream aus [[lib_de:System.Net.URLClient.IURLResponse.ContentStream|ContentStream]] lesen.&lt;br /&gt;
* Sie können die Antwort-Header mit [[lib_de:System.Net.URLClient.IURLResponse.Headers|Headers]], [[lib_de:System.Net.HttpClient.IHTTPResponse.HeaderValue|HeaderValue]], [[lib_de:System.Net.HttpClient.IHTTPResponse.ContainsHeader|ContainsHeader]] oder einer der folgenden Hilfseigenschaften lesen, die den Wert von allgemeinen HTTP-Antwort-Header-Feldern enthalten: [[lib_de:System.Net.HttpClient.IHTTPResponse.ContentCharSet|ContentCharSet]], [[lib_de:System.Net.HttpClient.IHTTPResponse.ContentEncoding|ContentEncoding]], [[lib_de:System.Net.HttpClient.IHTTPResponse.ContentLanguage|ContentLanguage]], [[lib_de:System.Net.HttpClient.IHTTPResponse.ContentLength|ContentLength]], [[lib_de:System.Net.HttpClient.IHTTPResponse.Date|Date]], [[lib_de:System.Net.HttpClient.IHTTPResponse.LastModified|LastModified]], [[lib_de:System.Net.URLClient.IURLResponse.MimeType|MimeType]].&lt;br /&gt;
* [[lib_de:System.Net.HttpClient.IHTTPResponse.Cookies|Cookies]] enthält die [[lib_de:System.Net.HttpClient.TCookies|Cookies]] der Serverantwort.&lt;br /&gt;
&lt;br /&gt;
==Verwalten von Cookies==&lt;br /&gt;
&lt;br /&gt;
Mit der Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]] der HTTP-Client-Komponente können Sie festlegen, ob Sie die vom Server in der Antwort gesendeten Cookies akzeptieren möchten.&lt;br /&gt;
Wenn [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]] {{True}} ist, speichert der HTTP-Client die empfangenen Cookies in seinem [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.CookieManager|CookieManager]].&lt;br /&gt;
&lt;br /&gt;
:{{Note| Der HTTP-Client fügt seine [[lib_de:System.Net.HttpClient.TCookieManager.Cookies|vorhandenen Cookies]] immer der Anforderung hinzu, unabhängig vom Wert von [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AllowCookies|AllowCookies]].}}&lt;br /&gt;
&lt;br /&gt;
==Behandeln von Umleitungen==&lt;br /&gt;
&lt;br /&gt;
Mit der Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.HandleRedirects|HandleRedirects]] steuern Sie, wie die HTTP-Client-Komponente Umleitungen behandelt. Der Standardwert ist {{True}}, was bedeutet, dass die HTTP-Client-Komponente Umleitungen automatisch folgt.&lt;br /&gt;
&lt;br /&gt;
Mit der Eigenschaft [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.MaxRedirects|MaxRedirects]] der HTTP-Client-Komponente geben Sie die maximale Anzahl an Umleitungen an, der die Komponente folgen darf. Wenn die HTTP-Client-Komponente die angegebene Anzahl an maximalen Umleitungen erreicht, löst sie eine Exception mit dem Typ [[lib_de:System.Net.HttpClient.ENetHTTPRequestException|ENetHTTPRequestException]] aus.&lt;br /&gt;
&lt;br /&gt;
==Behandeln des Herunterladens der Antwortdaten==&lt;br /&gt;
&lt;br /&gt;
Beim Herunterladen der Antwort auf Ihre Anforderung durch den HTTP-Client wird laufend das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] Ihrer HTTP-Anforderung ausgelöst. Sehen Sie eine Ereignisbehandlungsroutine für [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] vor, um den Fortschritt beim Herunterladen der Antwortdaten zu verfolgen. Ihre Ereignisbehandlungsroutine erhält die folgenden Parameter:&lt;br /&gt;
&lt;br /&gt;
* {{Arg|Sender}} ist Ihr HTTP-Anforderungsobjekt.&lt;br /&gt;
* {{Arg|AContentLength}} ist die erwartete Länge der Antwortdaten in Byte.&lt;br /&gt;
* {{Arg|AReadCount}} ist die Länge der Antwortdaten in Byte, die der HTTP-Client bisher heruntergeladen hat.&lt;br /&gt;
* {{Arg|Abort}} ist ein boolescher Parameter zum Abbrechen des Herunterladens.&lt;br /&gt;
&lt;br /&gt;
Am Ende des Herunterladens wird [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] zum letzten Mal ausgelöst, und {{Arg|AContentLength}} und {{Arg|AReadCount}} enthalten die gleichen Werte. Kurz danach wird [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnRequestCompleted|OnRequestCompleted]] ausgelöst.&lt;br /&gt;
&lt;br /&gt;
===Verfolgen des Fortschritts beim Herunterladen der Antwortdaten===&lt;br /&gt;
&lt;br /&gt;
Verwenden Sie zum Verfolgen des Fortschritts der heruntergeladenen Daten die Werte von {{Arg|AContentLength}} und {{Arg|AReadCount}} in der Ereignisbehandlungsroutine [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]].&lt;br /&gt;
In folgendem Beispiel wird der Prozentsatz der heruntergeladenen Daten berechnet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPRequest1ReceiveData(const Sender: TObject;&lt;br /&gt;
AContentLength, AReadCount: Int64; var Abort: Boolean);&lt;br /&gt;
var&lt;br /&gt;
    percentageDownloaded:Double;&lt;br /&gt;
begin&lt;br /&gt;
    if AContentLength &amp;gt; 0 then&lt;br /&gt;
        percentageDownloaded :=  (AReadCount / AContentLength) * 100;&lt;br /&gt;
    else&lt;br /&gt;
        // the server did not provide the Content-Length header&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm1::NetHTTPRequest1ReceiveData(TObject * const Sender, __int64 AContentLength,&lt;br /&gt;
     __int64 AReadCount, bool &amp;amp;Abort)&lt;br /&gt;
{&lt;br /&gt;
    float percentageDownloaded;&lt;br /&gt;
    if (AContentLength &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        percentageDownloaded = ((float)AReadCount / (float)AContentLength) * 100.f;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // the server did not provide the Content-Length header&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Abbrechen des Herunterladens der Antwortdaten===&lt;br /&gt;
&lt;br /&gt;
Ändern Sie in der Ereignisbehandlungsroutine [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnReceiveData|OnReceiveData]] den Wert von {{Arg|Abort}} in {{True}}, um das Herunterladen der Antwortdaten abzubrechen.&lt;br /&gt;
&lt;br /&gt;
==Senden einer Anforderung mit benutzerdefinierten Headern==&lt;br /&gt;
&lt;br /&gt;
Sie können sowohl mit der HTTP-Client-Komponente als auch mit der HTTP-Anforderungs-Komponente benutzerdefinierte Header festlegen. &lt;br /&gt;
Folgende benutzerdefinierte Header können Sie festlegen:&lt;br /&gt;
&lt;br /&gt;
* In der HTTP-Client-Komponente:&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.Accept|Accept]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AcceptCharSet|AcceptCharSet]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AcceptEncoding|AcceptEncoding]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.AcceptLanguage|AcceptLanguage]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.ContentType|ContentType]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.UserAgent|UserAgent]]&lt;br /&gt;
&lt;br /&gt;
* In der HTTP-Anforderungs-Komponente:&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Accept|Accept]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptCharSet|AcceptCharSet]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptEncoding|AcceptEncoding]]&lt;br /&gt;
** [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.AcceptLanguage|AcceptLanguage]]&lt;br /&gt;
&lt;br /&gt;
Beim [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Execute|Ausführen]] einer Anforderung kombiniert die Methode [[lib_de:System.Net.HttpClient.THTTPClient.Execute|THTTPClient.Execute]] des HTTP-Frameworks die benutzerdefinierten Header aus der HTTP-Client-Komponente und aus der entsprechenden HTTP-Anforderungs-Komponente und fügt diese Header der endgültigen Anforderung hinzu.&lt;br /&gt;
&lt;br /&gt;
==Behandeln von sicheren Verbindungen==&lt;br /&gt;
&lt;br /&gt;
Die HTTP-Client-Komponente unterstützt sichere Verbindungen (HTTPS). Das HTTP-Framework behandelt jede auftretende Zertifikatsanforderung automatisch und löst bei Bedarf das passende Ereignis aus:&lt;br /&gt;
&lt;br /&gt;
* [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnNeedClientCertificate|OnNeedClientCertificate]], wenn ein Server ein Zertifikat vom Client anfordert.&lt;br /&gt;
* [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnValidateServerCertificate|OnValidateServerCertificate]], wenn der Server ein ungültiges Zertifikat bereitstellt.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen über die Behandlung von Zertifikaten finden Sie in den Abschnitten [[Verwenden eines HTTP-Clients#Behandeln serverseitiger Zertifikate|Behandeln serverseitiger Zertifikate]] und [[Verwenden eines HTTP-Clients#Behandeln clientseitiger Zertifikate|Behandeln clientseitiger Zertifikate]].&lt;br /&gt;
&lt;br /&gt;
==Behandeln von Authentifizierung und Zertifikaten==&lt;br /&gt;
&lt;br /&gt;
===Behandeln der HTTP-Basiszugriffsauthentifizierung===&lt;br /&gt;
&lt;br /&gt;
Wenn Sie eine HTTP-Anforderung an einen Server senden, der eine [[Wikipedia:Basic access authentication|HTTP-Basiszugriffsauthentifizierung]] erfordert, wird das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]] Ihres HTTP-Client-Objekts ausgelöst. Um Ihre Anmeldedaten für den Zugriff zu übermitteln, erstellen Sie eine Ereignisbehandlungsroutine für dieses Ereignis. Falls der Wert des zweiten Parameters, den die Ereignisbehandlungsroutine erhält ({{Arg|AnAuthTarget}}), [[lib_de:System.Net.URLClient.TAuthTargetType|TAuthTargetType.Server]] ist, füllen Sie die Variablen {{Arg|AUserName}} und {{Arg|APassword}} mit Ihrem Benutzernamen und Passwort für den Proxy. Zum Beispiel:&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;&lt;br /&gt;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string;&lt;br /&gt;
  var AUserName, APassword: string; var AbortAuth: Boolean;&lt;br /&gt;
  var Persistence: TAuthPersistenceType);&lt;br /&gt;
begin&lt;br /&gt;
  if AnAuthTarget = TAuthTargetType.Server then&lt;br /&gt;
  begin&lt;br /&gt;
    AUserName := &#039;MyUsername&#039;;&lt;br /&gt;
    APassword := &#039;1234&#039;;&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm1::NetHTTPClient1AuthEvent(TObject * const Sender,&lt;br /&gt;
  TAuthTargetType AnAuthTarget, const UnicodeString ARealm,&lt;br /&gt;
  const UnicodeString AURL, UnicodeString &amp;amp;AUserName, UnicodeString &amp;amp;APassword,&lt;br /&gt;
  bool &amp;amp;AbortAuth, TAuthPersistenceType &amp;amp;Persistence)&lt;br /&gt;
{&lt;br /&gt;
    if (AnAuthTarget == TAuthTargetType::Server) {&lt;br /&gt;
        AUserName = &amp;quot;MyUsername&amp;quot;;&lt;br /&gt;
        APassword = &amp;quot;1234&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ihre Ereignisbehandlungsroutine erhält auch den Bereich des HTTP-Servers, für den eine Authentifizierung erforderlich ist ({{Arg|ARealm}}), und den Ziel-URL Ihrer Anforderung ({{Arg|AURL}}).&lt;br /&gt;
&lt;br /&gt;
Um die HTTP-Authentifizierung abzubrechen, ändern Sie den Wert von {{Arg|AbortAuth}} in {{True}}.&lt;br /&gt;
&lt;br /&gt;
===Senden einer Anforderung hinter einem Proxy===&lt;br /&gt;
&lt;br /&gt;
Wenn Sie sich hinter einem [[Wikipedia:Proxy server|Proxy]] befinden, für den eine Authentifizierung erforderlich ist, können Sie die [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.ProxySettings|Proxy-Einstellungen]] festlegen, die für die Authentifizierung verwendet werden.&lt;br /&gt;
Das folgende Beispiel zeigt das Vorgehen dabei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.ProxySettings := TProxySettings.Create(&#039;192.168.1.1&#039;, 8080, &#039;MyUserName&#039;, &#039;MyPassword&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TProxySettings  MyProxySettings(&amp;quot;192.168.1.1&amp;quot;, 8080, &amp;quot;MyUserName&amp;quot;, &amp;quot;MyPassword&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;ProxySettings = MyProxySettings;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit zum Festlegen Ihrer Proxy-Einstellungen stellt ein URL-String mit den Proxy-bezogenen Informationen dar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.ProxySettings := TProxySettings.Create(&#039;http://MyUserName:MyPassword@192.168.1.1:8080&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TProxySettings  MyProxySettings(&amp;quot;http://MyUserName:MyPassword@192.168.1.1:8080&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;ProxySettings = MyProxySettings;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternativ können Sie die Anmeldeinformationen für die Proxy-Authentifizierung in der Ereignisbehandlungsroutine [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]] angeben. Siehe den Abschnitt [[Verwenden eines HTTP-Clients#Behandeln der HTTP-Basiszugriffsauthentifizierung|Behandeln der HTTP-Basiszugriffsauthentifizierung]]. Der Wert von {{Code|AnAuthTarget}} muss {{Const|TAuthTargetType.Proxy}} anstelle von {{Const|TAuthTargetType.Server}} sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behandeln von System-Proxy-Einstellungen mit einem HTTP-Client&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In der folgenden Tabelle wird erklärt, wie der HTTP-Client die System-Proxy-Einstellungen auf verschiedenen Plattformen behandelt:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
!Plattform&lt;br /&gt;
!Verhalten&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Windows&lt;br /&gt;
|&lt;br /&gt;
Der HTTP-Client verwendet die System-Proxy-Einstellungen. Sie können die System-Proxy-Einstellungen umgehen und alternative Proxy-Einstellungen für den HTTP-Client bereitstellen.&lt;br /&gt;
&lt;br /&gt;
Um die System-Proxy-Einstellungen zu umgehen, erstellen Sie Proxy-Einstellungen für den HTTP-Client und geben {{Code|&amp;lt;nowiki&amp;gt;http://direct&amp;lt;/nowiki&amp;gt;}} als URL an. &lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
OS X&lt;br /&gt;
|&lt;br /&gt;
Der HTTP-Client verwendet immer die System-Proxy-Einstellungen. Auch wenn Sie alternative Proxy-Einstellungen für den HTTP-Client bereitstellen, verwendet der HTTP-Client die System-Proxy-Einstellungen.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
iOS&lt;br /&gt;
|&lt;br /&gt;
Der HTTP-Client verwendet immer die System-Proxy-Einstellungen. Auch wenn Sie alternative Proxy-Einstellungen für den HTTP-Client bereitstellen, verwendet der HTTP-Client die System-Proxy-Einstellungen.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Android&lt;br /&gt;
|&lt;br /&gt;
Der HTTP-Client verwendet die System-Proxy-Einstellungen. Sie können diese Einstellungen nicht umgehen, aber Sie können alternative Proxy-Einstellungen für den HTTP-Client bereitstellen.&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Linux&lt;br /&gt;
|&lt;br /&gt;
Der HTTP-Client verwendet die System-Proxy-Einstellungen. Sie können diese Einstellungen nicht umgehen, aber Sie können alternative Proxy-Einstellungen für den HTTP-Client bereitstellen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:{{Note| Wenn das System keine Proxy-Einstellungen festlegt (die Verbindung ist direkt), wird dies auch als &amp;quot;Einstellung&amp;quot; betrachtet. Auf iOS oder OS X ohne System-Proxy-Einstellungen können Sie beispielsweise keine Proxy-Einstellungen für den HTTP-Client bereitstellen. Die Einstellungen, die Sie bereitstellen, werden ignoriert, weil die Systemeinstellungen (die Einstellung &amp;quot;Kein Proxy&amp;quot;) verwendet werden.}}&lt;br /&gt;
&lt;br /&gt;
===Verwalten der Speicherung von Benutzer-Anmeldeinformationen===&lt;br /&gt;
&lt;br /&gt;
Mit [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient|TNetHTTPClient]] können Sie Anmeldeinformationen für die HTTP- oder Proxy-Authentifizierung speichern. Gespeicherte [[lib_de:System.Net.URLClient.TCredentialsStorage.TCredential|Anmeldeinformationen]] können einen Benutzernamen, ein Passwort, einen [[lib_de:System.Net.URLClient.TAuthTargetType|Zieltyp für die Authentifizierung]], einen Bereich und einen Ziel-URL umfassen.&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel zeigt, wie mit [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.CredentialsStorage|TNetHTTPClient.CredentialsStorage]] Anmeldeinformationen gespeichert werden und dann mit diesen Anmeldeinformationen die Authentifizierung bei der Verbindung mit einem HTTP-Server, der eine grundlegende Authentifizierung erfordert, vorgenommen wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Erstellen der Anmeldeinformationen und Hinzufügen zu Ihrem Anmeldeinformationsspeicher:&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
NetHTTPClient1.CredentialsStorage.AddCredentials(TCredentialsStorage.TCredential.Create(TAuthTargetType.Server, &#039;&#039;, &#039;&#039;, &#039;MyUserName&#039;, &#039;MyPassword&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
TCredentialsStorage::TCredential *MyCredential = new TCredentialsStorage::TCredential(TAuthTargetType::Server, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;MyUserName&amp;quot;, &amp;quot;MyPassword&amp;quot;);&lt;br /&gt;
NetHTTPClient1-&amp;gt;CredentialsStorage-&amp;gt;AddCredential(*MyCredential);&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Verwenden der gespeicherten Anmeldeinformationen.&lt;br /&gt;
&lt;br /&gt;
Sie können beispielsweise eine [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.OnAuthEvent|OnAuthEvent]]-Ereignisbehandlungsroutine schreiben, in der Sie:&lt;br /&gt;
* Mit [[lib_de:System.Net.URLClient.TCredentialsStorage.FindAccurateCredential|TCredentialsStorage.FindAccurateCredential]] nach Anmeldeinformationen suchen, die dem erforderlichen Authentifizierungstyp entsprechen ({{Code|TAuthTargetType.Server}}).&lt;br /&gt;
* Den Benutzernamen und das Passwort aus den entsprechenden Anmeldeinformationen für die Authentifizierung verwenden.&lt;br /&gt;
&amp;lt;l s=&amp;quot;delphi&amp;quot; /&amp;gt;&#039;&#039;&#039;{{Delphi}}:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;&lt;br /&gt;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,&lt;br /&gt;
  APassword: string; var AbortAuth: Boolean;&lt;br /&gt;
  var Persistence: TAuthPersistenceType);&lt;br /&gt;
var&lt;br /&gt;
    MyCredential: TCredentialsStorage.TCredential;&lt;br /&gt;
begin&lt;br /&gt;
    MyCredential := NetHTTPClient1.CredentialsStorage.FindAccurateCredential(AnAuthTarget, &#039;&#039;);&lt;br /&gt;
    AUserName := MyCredential.UserName;&lt;br /&gt;
    APassword := MyCredential.Password;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;delphi&amp;quot; /&amp;gt;&amp;lt;l s=&amp;quot;cpp&amp;quot; /&amp;gt;&#039;&#039;&#039;C++:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void __fastcall TForm2::NetHTTPClient1AuthEvent(TObject * const Sender, TAuthTargetType AnAuthTarget,&lt;br /&gt;
  const UnicodeString ARealm, const UnicodeString AURL,&lt;br /&gt;
  UnicodeString &amp;amp;AUserName, UnicodeString &amp;amp;APassword, bool &amp;amp;AbortAuth,&lt;br /&gt;
  TAuthPersistenceType &amp;amp;Persistence)&lt;br /&gt;
{&lt;br /&gt;
    TCredentialsStorage::TCredential MyCredential;&lt;br /&gt;
&lt;br /&gt;
    MyCredential = NetHTTPClient1-&amp;gt;CredentialsStorage-&amp;gt;FindAccurateCredential(AnAuthTarget, &amp;quot;&amp;quot;);&lt;br /&gt;
    AUserName = MyCredential.UserName;&lt;br /&gt;
    APassword = MyCredential.Password;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&amp;lt;l e=&amp;quot;cpp&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Behandeln serverseitiger Zertifikate===&lt;br /&gt;
&lt;br /&gt;
Wenn der Server ein SSL-Zertifikat bereitstellt, dieses Zertifikat aber ungültig ist, wird das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnValidateServerCertificate|OnValidateServerCertificate]] ausgelöst. Erstellen Sie eine Ereignisbehandlungsroutine für {{Code|OnValidateServerCertificate}}, damit Sie das Serverzertifikat ({{Arg|Certificate}}) überprüfen und festlegen können, ob Sie es akzeptieren oder nicht. Wenn Sie das Serverzertifikat akzeptieren, ändern Sie den Wert des Parameters {{Arg|Accept}} in {{True}}.&lt;br /&gt;
&lt;br /&gt;
===Behandeln clientseitiger Zertifikate===&lt;br /&gt;
&lt;br /&gt;
Wenn für den Server ein Client-Zertifikat erforderlich ist, wird das Ereignis [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.OnNeedClientCertificate|OnNeedClientCertificate]] ausgelöst. Erstellen Sie eine Ereignisbehandlungsroutine für {{Code|OnNeedClientCertificate}}, damit Sie Ihre Liste der Client-Zertifikate ({{Arg|ACertificateList}}) überprüfen und das Zertifikat festlegen können, das Sie an den Server senden möchten. Um ein Zertifikat aus der Liste zu senden, ändern Sie den Wert von {{Arg|AnIndex}} in den Index des Zielzertifikats in {{Arg|ACertificateList}}.&lt;br /&gt;
&lt;br /&gt;
: {{Note| Wenn die HTTP-Methode der ersten Anforderung an einen Server, der ein clientseitiges Zertifikat erfordert, nicht HEAD oder GET (z. B. POST) ist, lautet der Statuscode der Serverantwort 413. Senden Sie immer zuerst eine HEAD- oder GET-Anforderung. Eine HEAD-Anforderung ist normalerweise vorzuziehen, weil weniger Daten übertragen werden.}}&lt;br /&gt;
&lt;br /&gt;
==Anfragen asynchron machen==&lt;br /&gt;
&lt;br /&gt;
Anfragen sind standardmäßig synchron. Während der Anfrage wird die Ausführung Ihrer Anwendung gestoppt, wenn Sie Ihre Anfrage starten, und wird nur fortgesetzt, wenn Sie eine Antwort vom Server oder der Anfrage-Zeitüberschreitung erhalten.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie möchten, dass Ihre Anfrage asynchron sind, damit die Anfragen nicht bei der Ausführung nicht gestoppt werden, müssen Sie die [[lib_de:System.Net.HttpClientComponent.TNetHTTPClient.Asynchronous|Asynchronous]]-Eigenschaft der Client-Komponente oder die [[lib_de:System.Net.HttpClientComponent.TNetHTTPRequest.Asynchronous|Asynchronous]]-Eigenschaft der Anfragekomponente aktivieren, abhängig von der Komponente, mit der Sie Ihre Anforderung ausführen möchten.&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [[lib_de:System.Net.URLClient|System.Net.URLClient]]&lt;br /&gt;
* [[lib_de:System.Net.HttpClient|System.Net.HttpClient]]&lt;br /&gt;
* [[lib_de:System.Net.HttpClientComponent|System.Net.HttpClientComponent]]&lt;br /&gt;
&lt;br /&gt;
* [[Verwenden von App-Tethering|Verwenden von App-Tethering]]&lt;br /&gt;
* [[Verwenden von Bluetooth|Verwenden von Bluetooth]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Geräteübergreifend]]&lt;br /&gt;
[[Category:AMMigrate]]&lt;br /&gt;
&lt;br /&gt;
[[en:Using an HTTP Client]]&lt;br /&gt;
[[fr:Utilisation d&#039;un client HTTP]]&lt;br /&gt;
[[ja:HTTP クライアントの使用]]&lt;/div&gt;</summary>
		<author><name>Alejandra.Barrientos</name></author>
	</entry>
</feed>