Freigeben über


Verknüpfung einer .NET MAUI iOS-App

Bei der Erstellung Ihrer App kann .NET Multi-platform App UI (.NET MAUI) einen Linker namens ILLink verwenden, um die Gesamtgröße der App zu reduzieren. ILLink reduziert die Größe, indem der vom Compiler erzeugte Zwischencode analysiert wird. Es entfernt nicht verwendete Methoden, Eigenschaften, Felder, Ereignisse, Strukturen und Klassen, um eine App zu erstellen, die nur Code und Assembly-Abhängigkeiten enthält, die für die Ausführung der App erforderlich sind.

Linkerverhalten

Der Linker unterstützt drei Modi für .NET MAUI-Apps auf iOS und Mac Catalyst:

  • Nicht verknüpfen. Durch die Deaktivierung der Verknüpfung wird sichergestellt, dass die Baugruppen nicht verändert werden.
  • Nur SDK-Assemblies verknüpfen. In diesem Modus lässt der Linker Ihre Assemblys unberührt und reduziert die Größe der SDK-Assemblys, indem Typen und Member entfernt werden, die Ihre App nicht verwendet.
  • Alle Assemblys verknüpfen. Wenn alle Assemblys verknüpft sind, führt der Linker zusätzliche Optimierungen durch, um Ihre App so klein wie möglich zu machen. Er ändert den Zwischencode für Den Quellcode, der Ihre App möglicherweise unterbrechen kann, wenn Sie Features verwenden, die einen Ansatz verwenden, der von der statischen Analyse des Linkers nicht erkannt werden kann. In diesen Fällen müssen Sie möglicherweise Anpassungen am Quellcode vornehmen, damit Ihre App ordnungsgemäß funktioniert.

Das Linker-Verhalten kann für jede Build-Konfiguration Ihrer App konfiguriert werden.

Warnung

Das Aktivieren des Linkers für die Debug-Konfiguration Ihrer App kann Ihre Debugging-Erfahrung beeinträchtigen, da dadurch möglicherweise Eigenschaftszugriffsfunktionen entfernt werden, die es Ihnen ermöglichen, den Zustand Ihrer Objekte zu überprüfen.

So konfigurieren Sie das Verhalten des Linkers in Visual Studio:

  1. Im Solution Explorer klicken Sie mit der rechten Maustaste auf Ihr .NET MAUI App Projekt und wählen Eigenschaften. Navigieren Sie dann zur Registerkarte iOS > Build und setzen Sie das Dropdown-Menü Linker-Verhalten auf Ihr gewünschtes Linker-Verhalten:

    Screenshot des Linker-Verhaltens für iOS in Visual Studio.

Code beibehalten

Wenn Sie den Trimmer verwenden, entfernt es manchmal Code, den Sie möglicherweise dynamisch aufgerufen haben, sogar indirekt. Sie können den Trimmer anweisen, Mitglieder beizubehalten, indem Sie sie mit dem DynamicDependency Attribut kommentieren. Dieses Attribut kann verwendet werden, um eine Abhängigkeit entweder von einem Typ und einer Teilmenge von Mitgliedern oder von bestimmten Mitgliedern auszudrücken.

Wichtig

Jedes Mitglied der BCL, bei dem nicht statisch festgestellt werden kann, dass es von der App verwendet wird, muss entfernt werden.

Das Attribut DynamicDependency kann auf Konstruktoren, Felder und Methoden angewendet werden:

[DynamicDependency("Helper", "MyType", "MyAssembly")]
static void RunHelper()
{
    var helper = Assembly.Load("MyAssembly").GetType("MyType").GetMethod("Helper");
    helper.Invoke(null, null);
}

In diesem Beispiel sorgt das DynamicDependency dafür, dass die Methode Helper beibehalten wird. Ohne das Attribut würde Helper die Kürzung vollständig entfernt MyAssembly oder entfernt MyAssembly , wenn sie nicht an anderer Stelle referenziert wird.

Das Attribut gibt das zu behaltende Mitglied über ein string oder über das DynamicallyAccessedMembers-Attribut an. Der Typ und die Assembly sind entweder implizit im Attributkontext oder explizit im Attribut angegeben (durch Type oder durch strings für den Typ und den Assemblynamen).

Die Typ- und Member-Zeichenfolgen verwenden eine Variation des Zeichenfolgenformats der Kommentar-ID aus der C#-Dokumentation ohne das Member-Präfix. Die Memberzeichenfolge sollte nicht den Namen des deklarierenden Typs enthalten und kann Parameter weglassen, um alle Member des angegebenen Namens beizubehalten. Die folgenden Beispiele zeigen gültige Verwendungen:

[DynamicDependency("Method()")]
[DynamicDependency("Method(System,Boolean,System.String)")]
[DynamicDependency("MethodOnDifferentType()", typeof(ContainingType))]
[DynamicDependency("MemberName")]
[DynamicDependency("MemberOnUnreferencedAssembly", "ContainingType", "UnreferencedAssembly")]
[DynamicDependency("MemberName", "Namespace.ContainingType.NestedType", "Assembly")]
// generics
[DynamicDependency("GenericMethodName``1")]
[DynamicDependency("GenericMethod``2(``0,``1)")]
[DynamicDependency("MethodWithGenericParameterTypes(System.Collections.Generic.List{System.String})")]
[DynamicDependency("MethodOnGenericType(`0)", "GenericType`1", "UnreferencedAssembly")]
[DynamicDependency("MethodOnGenericType(`0)", typeof(GenericType<>))]

Beibehalten von Assemblys

Es ist möglich, Assemblys anzugeben, die vom Kürzungsprozess ausgeschlossen werden sollten, während andere Assemblys gekürzt werden können. Dieser Ansatz kann nützlich sein, wenn Sie das DynamicDependency Attribut nicht einfach verwenden können, oder den Code, der gekürzt wird, nicht steuern.

Wenn alle Assemblys gekürzt werden, können Sie den Trimmer anweisen, eine Assembly zu überspringen, indem Sie ein TrimmerRootAssembly MSBuild-Element in der Projektdatei festlegen:

<ItemGroup>
  <TrimmerRootAssembly Include="MyAssembly" />
</ItemGroup>

Hinweis

Die Erweiterung .dll ist nicht erforderlich, wenn die Eigenschaft TrimmerRootAssembly MSBuild eingestellt wird.

Wenn der Trimmer eine Assembly überspringt, wird sie als gewurzelt betrachtet, was bedeutet, dass sie und alle ihre statisch verstandenen Abhängigkeiten beibehalten werden. Sie können zusätzliche Assemblies überspringen, indem Sie weitere TrimmerRootAssembly MSBuild-Eigenschaften zu <ItemGroup> hinzufügen.

Beibehalten von Assemblys, Typen und Elementen

Sie können den Trimmer an eine XML-Beschreibungsdatei übergeben, die angibt, welche Assemblys, Typen und Member aufbewahrt werden müssen.

Um ein Element beim Kürzen aller Assemblys auszuschließen, legen Sie das TrimmerRootDescriptor MSBuild-Element in der Projektdatei auf die XML-Datei fest, die die auszuschließenden Member definiert:

<ItemGroup>
  <TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>

Die XML-Datei verwendet dann das Trimmerdeskriptorformat, um zu definieren, welche Member ausgeschlossen werden sollen:

<linker>
  <assembly fullname="MyAssembly">
    <type fullname="MyAssembly.MyClass">
      <method name="DynamicallyAccessedMethod" />
    </type>
  </assembly>
</linker>

In diesem Beispiel gibt die XML-Datei eine Methode an, auf die dynamisch von der App zugegriffen wird, die von der Kürzung ausgeschlossen wird.

Wenn eine Assembly, ein Typ oder ein Element im XML-Code aufgeführt ist, wird die Standardaktion beibehalten. Dies bedeutet, dass der Trimmer unabhängig davon, ob er verwendet wird oder nicht, in der Ausgabe beibehalten wird.

Hinweis

Die Erhaltungstags sind mehrdeutig inklusive. Wenn Sie nicht die nächste Detailebene angeben, enthält sie alle untergeordneten Elemente. Wenn eine Assembly ohne Typen aufgeführt ist, werden alle Typen und Member der Assembly beibehalten.

Kennzeichnen einer Assembly als sicher zuschneiden

Wenn Sie über eine Bibliothek in Ihrem Projekt verfügen oder Entwickler einer wiederverwendbaren Bibliothek sind und möchten, dass der Trimmer Die Assembly als trimmbar behandeln kann, können Sie die Assembly als sicher markieren, indem Sie die IsTrimmable MSBuild-Eigenschaft zur Projektdatei für die Assembly hinzufügen:

<PropertyGroup>
    <IsTrimmable>true</IsTrimmable>
</PropertyGroup>

Dadurch wird Ihre Assembly als „kürzbar“ gekennzeichnet, und Kürzungswarnungen werden für dieses Projekt aktiviert. „Kürzbar“ bedeutet, dass Ihre Bibliothek als mit Kürzungen kompatibel gilt und beim Erstellen der Bibliothek keine Kürzungswarnungen enthalten sollte. Wenn die Assembly in einer gekürzten App verwendet wird, werden die nicht verwendeten Member in der finalen Ausgabe gekürzt.

Wenn Sie die MSBuild-Eigenschaft IsTrimmable in Ihrer Projektdatei auf true setzen, wird das Attribut AssemblyMetadata in Ihre Assembly eingefügt:

[assembly: AssemblyMetadata("IsTrimmable", "True")]

Alternativ können Sie das AssemblyMetadata-Attribut in Ihre Assembly einfügen, ohne die IsTrimmable MSBuild-Eigenschaft zur Projektdatei für Ihre Baugruppe hinzugefügt zu haben.

Hinweis

Wenn die IsTrimmable-MSBuild-Eigenschaft für eine Assembly festgelegt ist, überschreibt dies das AssemblyMetadata("IsTrimmable", "True")-Attribut. Damit können Sie eine Baugruppe für das Trimmen auswählen, auch wenn sie das Attribut nicht hat, oder das Trimmen einer Baugruppe, die das Attribut hat, deaktivieren.

Unterdrücken von Codeanalysewarnungen

Wenn der Trimmer aktiviert ist, entfernt er il, der nicht statisch erreichbar ist. Apps, die Reflexion oder andere Muster verwenden, die die dynamischen Abhängigkeiten erstellen, können durch das Kürzen beschädigt werden. Um solche Muster zu warnen, sollten Bibliotheksautoren beim Markieren einer Assembly als sicher zuschneiden die SuppressTrimAnalysisWarnings MSBuild-Eigenschaft auf falseFolgendes festlegen:

<PropertyGroup>
  <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
</PropertyGroup>

Dies schließt Warnungen zur gesamten App ein, einschließlich Ihres eigenen Codes, Bibliothekscodes und Frameworkcodes.

Anzeigen ausführlicher Warnungen

Die Trimm-Analyse erzeugt höchstens eine Warnung für jede Baugruppe, die von einem PackageReference stammt, was darauf hinweist, dass die Interna der Baugruppe nicht mit dem Trimmen kompatibel sind. Als Bibliotheksautor sollten Sie, wenn Sie eine Assembly als Kürzung sicher markieren, einzelne Warnungen für alle Assemblys aktivieren, indem Sie die TrimmerSingleWarn MSBuild-Eigenschaft auf false:

<PropertyGroup>
  <TrimmerSingleWarn>false</TrimmerSingleWarn>
</PropertyGroup>

Zeigen Sie alle detaillierten Warnungen an, anstatt sie auf eine einzelne Warnung pro Assembly zu reduzieren.