Mono interpret v systémech iOS a Mac Catalyst
Když zkompilujete aplikaci .NET Multi-Platform App UI (.NET MAUI) pro iOS nebo Mac Catalyst, kompilátor změní kód aplikace na jazyk MSIL (Microsoft Intermediate Language). Když spustíte aplikaci pro iOS v simulátoru nebo aplikaci Mac Catalyst, modul CLR (Common Language Runtime) .NET zkompiluje jazyk MSIL pomocí kompilátoru JIT (Just in Time). Za běhu se jazyk MSIL zkompiluje do nativního kódu, který se dá spustit ve správné architektuře vaší aplikace.
Existuje však omezení zabezpečení pro iOS nastavené společností Apple, které zakáže spuštění dynamicky generovaného kódu na zařízení. Podobně je provádění dynamicky generovaného kódu zakázáno v aplikacích pro iOS běžících v architektuře ARM64 v simulátoru a v aplikacích Mac Catalyst běžících v architektuře ARM64. Aby bylo toto omezení splněno, aplikace pro iOS a Mac Catalyst používají kompilátor AOT (Head of Time) ke kompilaci spravovaného kódu. Tím se vytvoří nativní binární soubor pro iOS, který lze nasadit na zařízení Apple nebo nativní binární soubor Mac Catalyst.
AOT poskytuje výhody díky zkrácení doby spuštění a různých dalších optimalizací výkonu. Zároveň ale omezuje použití určitých funkcí ve vaší aplikaci:
- Existuje omezená podpora obecných typů. V době kompilace nelze určit každou možnou obecnou instanci. Příčinou mnoha problémů specifických pro iOS v buildech vydaných verzí .NET MAUI je toto omezení.
- Dynamické generování kódu není povolené. To znamená, že
System.Relection.Emit
není k dispozici, neexistuje žádná podporaSystem.Runtime.Remoting
a některá použití dynamického typu C# nejsou povolená.
Když dojde k omezení AOT, System.ExecutionEngineException
vyvolá se zpráva "Pokus o metodu kompilace JIT při spuštění v režimu pouze aot".
Interpret Mono tato omezení překončí, zatímco omezení platformy zabíjí. Umožňuje interpretovat některé části aplikace za běhu a kompilovat zbytek AOT. Existuje však několik potenciálních nevýhod použití interpreta v produkční aplikaci:
- I když je interpret povolený, velikost aplikace se obvykle výrazně zmenšuje, v některých případech se velikost aplikace může zvětšit.
- Rychlost spouštění aplikací bude pomalejší, protože interpretovaný kód běží pomaleji než zkompilovaný kód AOT. Toto snížení rychlosti provádění může být v rozsahu od nepředpojitelného až po nepřijatelné, takže testování výkonu by mělo být provedeno.
- Nativní trasování zásobníku v sestavách o chybách je méně užitečné, protože budou obsahovat obecné rámce z interpretu, který nezmiňuje kód, který se spouští. Trasování spravovaného zásobníku se ale nezmění.
Interpret je ve výchozím nastavení povolený pro sestavení ladění .NET MAUI a je možné ho povolit pro sestavení vydaných verzí.
Tip
Pokud vaše aplikace .NET MAUI pro iOS nebo aplikace Mac Catalyst založená na ARM64 funguje správně jako ladicí sestavení, ale pak dojde k chybovému ukončení jako sestavení vydané verze, zkuste povolit interpreta pro sestavení vydané verze vaší aplikace. Může to být, že vaše aplikace nebo jedna z jejích knihoven používá funkci, která vyžaduje interpret.
Povolení interpreta
Interpret Mono je možné povolit v buildech verzí pro iOS nastavením $(UseInterpreter)
vlastnosti MSBuild do true
souboru projektu aplikace .NET MAUI:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<UseInterpreter>true</UseInterpreter>
</PropertyGroup>
Interpret lze také povolit pro buildy verze Mac Catalyst na ARM64:
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'maccatalyst-arm64' and '$(Configuration)' == 'Release'">
<UseInterpreter>true</UseInterpreter>
</PropertyGroup>
Upozorňující
Nepovolujte interpreta pro sestavení vydaných verzí v Androidu, protože zakazuje kompilaci JIT.
V systému iOS a Mac Catalyst lze interpret povolit také pomocí $(MtouchInterpreter)
vlastnosti MSBuild. Tato vlastnost volitelně přebírá čárkami oddělený seznam sestavení, která se mají interpretovat. Kromě toho all
lze použít k určení všech sestavení a při předponě se znaménkem minus bude sestavení Zkompilováno AOT. To umožňuje:
- Interpretovat všechna sestavení zadáním
all
nebo AOT kompilovat vše zadáním-all
. - Interpretujte jednotlivá sestavení zadáním MyAssembly nebo AOT kompilovat jednotlivá sestavení zadáním -MyAssembly.
- Kombinace a shoda pro interpretaci některých sestavení a AOT kompilace jiných sestavení.
Upozorňující
Interpret není kompatibilní s nativním nasazením AOT, a proto $(UseInterpreter)
vlastnosti MSBuild $(MtouchInterpreter)
nemají při použití nativní AOT žádný vliv. Další informace najdete v tématu Nativní nasazení AOT.
Následující příklad ukazuje, jak interpretovat všechna sestavení s výjimkou System.Xml.dll:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<!-- Interpret everything, except System.Xml.dll -->
<MtouchInterpreter>all,-System.Xml</MtouchInterpreter>
</PropertyGroup>
Následující příklad ukazuje, jak AOT kompilovat všechna sestavení s výjimkou System.Numerics.dll:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<!-- AOT everything, except System.Numerics.dll, which will be interpreted -->
<MtouchInterpreter>-all,System.Numerics</MtouchInterpreter>
</PropertyGroup>
Důležité
Rámec zásobníku spuštěný interpretem neposkytuje užitečné informace. Vzhledem k tomu, že interpret může být zakázán na základě sestavení, je možné mít snímky zásobníku z některých sestavení přesně znázorněné v sestavách o chybách.
Případně můžete pomocí následujícího příkladu zkompilovat všechna sestavení AOT a zároveň umožnit interpretovi provádět dynamické generování kódu:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios')) and '$(Configuration)' == 'Release'">
<MtouchInterpreter>-all</MtouchInterpreter>
</PropertyGroup>
Dalším běžným scénářem, kdy se interpret někdy vyžaduje, je aplikace .NET MAUI Mac Catalyst spuštěná v architektuře ARM64, která může vyvolat výjimku při spuštění. Tuto výjimku spuštění je často možné opravit povolením interpreta:
<PropertyGroup Condition="'$(RuntimeIdentifier)' == 'maccatalyst-arm64' and '$(Configuration)' == 'Release'">
<MtouchInterpreter>-all,MyAssembly</MtouchInterpreter>
</PropertyGroup>