Jak funguje Xamarin.Mac
Ve většině případů se vývojář nebude muset starat o vnitřní "magii" Xamarin.Mac, ale s hrubým pochopením toho, jak věci fungují pod kapucí, vám pomůžou při interpretaci stávající dokumentace s objektivem C# a problémy s laděním při jejich vzniku.
V Xamarin.Mac aplikace přemístit dva světy: je Objective-C založený modul runtime obsahující instance nativních tříd (NSString
atd NSApplication
.) a existuje modul runtime jazyka C# obsahující instance spravovaných tříd (System.String
atd HttpClient
.). Mezi těmito dvěma světy Xamarin.Mac vytvoří obousměrný most, aby aplikace mohl volat metody (selektory) v Objective-C (například NSApplication.Init
) a Objective-C volat metody jazyka C# aplikace zpět (například metody na delegátovi aplikace). Obecně platí, že volání se Objective-C zpracovávají transparentně prostřednictvím volání P/Invokes a některé kód modulu runtime Xamarin poskytuje.
Zveřejnění tříd nebo metod jazyka C# pro Objective-C
Aby Objective-C se ale mohl vrátit zpět k objektům C# aplikace, musí být vystaveny způsobem, který Objective-C dokáže pochopit. To se provádí prostřednictvím Register
atributů a Export
atributů. Podívejte se na následující příklad:
[Register ("MyClass")]
public class MyClass : NSObject
{
[Export ("init")]
public MyClass ()
{
}
[Export ("run")]
public void Run ()
{
}
}
V tomto příkladu Objective-C bude modul runtime nyní vědět o třídě volané s volanými MyClass
init
selektory a run
.
Ve většině případů se jedná o podrobnosti implementace, které může vývojář ignorovat, protože většina zpětného volání, kterou aplikace přijímá, bude buď prostřednictvím přepsání metod u base
tříd (například AppDelegate
, , Delegates
DataSources
), nebo akcí předávaných do rozhraní API. Ve všech těchto případech Export
nejsou atributy v kódu jazyka C# nezbytné.
Runthrough konstruktoru
V mnoha případech bude vývojář muset vystavit rozhraní API pro vytváření tříd jazyka C# aplikace do Objective-C modulu runtime, aby bylo možné vytvořit instanci z míst, jako je volání v storyboardu nebo souborech XIB. Tady je pět nejběžnějších konstruktorů používaných v aplikacích Xamarin.Mac:
// Called when created from unmanaged code
public CustomView (IntPtr handle) : base (handle)
{
Initialize ();
}
// Called when created directly from a XIB file
[Export ("initWithCoder:")]
public CustomView (NSCoder coder) : base (coder)
{
Initialize ();
}
// Called from C# to instance NSView with a Frame (initWithFrame)
public CustomView (CGRect frame) : base (frame)
{
}
// Called from C# to instance NSView without setting the frame (init)
public CustomView () : base ()
{
}
// This is a special case constructor that you call on a derived class when the derived called has an [Export] constructor.
// For example, if you call init on NSString then you don’t want to call init on NSObject.
public CustomView () : base (NSObjectFlag.Empty)
{
}
Vývojář by měl obecně opustit IntPtr
a NSCoder
konstruktory, které se vygenerují při vytváření některých typů, jako je například vlastní NSViews
. Pokud Xamarin.Mac potřebuje volat jeden z těchto konstruktorů v reakci na Objective-C požadavek modulu runtime a odebrali jste ho, aplikace dojde k chybovému ukončení v nativním kódu a může být obtížné přesně zjistit problém.
Správa paměti a cykly
Správa paměti v Xamarin.Mac je mnoha způsoby velmi podobná Xamarin.iOS. Jedná se také o komplexní téma, které je nad rámec tohoto dokumentu. Přečtěte si osvědčené postupy pro paměť a výkon.
Kompilace předem
Aplikace .NET se obvykle při vytváření nekompilují do strojového kódu, místo toho se kompilují do přechodné vrstvy s názvem IL kód, který se při spuštění aplikace zkompiluje do strojového kódu.
Doba potřebná k kompilaci mono runtime do JIT může zpomalit spuštění aplikace Xamarin.Mac až o 20 %, protože to trvá, než se vygeneruje potřebný strojový kód.
Z důvodu omezení uložených společností Apple pro iOS není kompilace kódu IL pro Xamarin.iOS k dispozici. Výsledkem je, že všechny aplikace Xamarin.iOS jsou během cyklu sestavení kompilované do strojového kódu předem ( AOT ).
Novinkou v Xamarin.Mac je schopnost AOT kódu IL během cyklu sestavení aplikace, stejně jako Xamarin.iOS. Xamarin.Mac používá hybridní přístup AOT , který zkompiluje většinu potřebného strojového kódu, ale umožňuje modulu runtime kompilovat potřebné trampoliny a flexibilitu pro pokračování v podpoře Reflex.Emit (a dalších případů použití, které aktuálně pracují na Xamarin.Mac).
Existují dvě hlavní oblasti, kde může AOT pomoci aplikaci Xamarin.Mac:
- Lepší "nativní" protokoly chyb – Pokud aplikace Xamarin.Mac dojde k chybovému ukončení v nativním kódu, což je běžný výskyt při provádění neplatných volání do rozhraní Cocoa API (například odeslání
null
do metody, která ji nepřijímá), nativní protokoly chyb s snímky JIT jsou obtížné analyzovat. Vzhledem k tomu, že snímky JIT nemají informace o ladění, budou existovat více řádků s šestnáctkovým posunem a bez povědomí o tom, co se děje. AOT generuje "skutečné" pojmenované snímky a trasování je mnohem jednodušší číst. To také znamená, že aplikace Xamarin.Mac bude lépe pracovat s nativními nástroji, jako jsou lldb a Nástroje. - Lepší výkon při spuštění – u velkých aplikací Xamarin.Mac s několika sekundami spuštění může kompilace JIT celý kód trvat značné množství času. AOT to funguje předem.
Povolení kompilace AOT
Funkce AOT je v Xamarin.Mac povolena poklikáním na název Project v Průzkumník řešení, přechodem na build Mac a přidáním --aot:[options]
do pole Další argumenty mmp( kde [options]
je jedna nebo více možností řízení typu AOT, viz níže). Příklad:
Důležité
Povolení kompilace AOT výrazně zvyšuje dobu sestavení, někdy až několik minut, ale může zlepšit dobu spuštění aplikace průměrem 20 %. V důsledku toho by měla být kompilace AOT povolena pouze v buildech vydaných verzí aplikace Xamarin.Mac.
Možnosti kompilace Aot
Při povolování kompilace AOT v aplikaci Xamarin.Mac je možné upravit několik různých možností:
none
- Žádná kompilace AOT. Toto je výchozí nastavení.all
- AOT zkompiluje každé sestavení v MonoBundle.core
- AOT zkompilujeXamarin.Mac
amscorlib
System
sestavení.sdk
- AOT kompilujeXamarin.Mac
sestavení BCL (Base Class Library).|hybrid
- Přidání této možnosti do jedné z výše uvedených možností umožňuje hybridní AOT, která umožňuje prokládání IL, ale bude mít za následek delší dobu kompilace.+
– Obsahuje jeden soubor pro kompilaci AOT.-
– Odebere jeden soubor z kompilace AOT.
--aot:all,-MyAssembly.dll
Například by povolovala kompilaci AOT na všech sestaveních v MonoBundle s výjimkouMyAssembly.dll
a --aot:core|hybrid,+MyOtherAssembly.dll,-mscorlib.dll
povolovala by hybridní kód AOT včetně MyOtherAssembly.dll
a vyloučení mscorlib.dll
.
Částečná statická registrar
Při vývoji aplikace Xamarin.Mac může být pro splnění termínů vývoje důležité minimalizovat dobu mezi dokončením změny a testováním. Strategie, jako je modularizace základů kódu a testů jednotek, můžou pomoct snížit dobu kompilace, protože snižují dobu, po kterou aplikace bude vyžadovat nákladné úplné opětovné sestavení.
Kromě toho a nové pro Xamarin.Mac, Částečná statická Registrar (jako průkopnický Xamarin.iOS) může výrazně snížit dobu spuštění aplikace Xamarin.Mac v konfiguraci ladění . Pochopení toho, jak použití částečné statické Registrar můžou vymáčknout téměř 5x vylepšení při spuštění ladění, bude mít trochu pozadí o tom, co registrar je, jaký je rozdíl mezi statickou a dynamickou a jakou "částečnou statickou" verzí dělá.
Informace o registrar
Pod kapucí jakékoli aplikace Xamarin.Mac leží architektura Cocoa od Společnosti Apple a Objective-C modulu runtime. Vytvoření mostu mezi tímto "nativním světem" a "spravovaným světem" jazyka C# je primární odpovědností Xamarin.Mac. Část této úlohy je zpracována metodou registrar, která se provádí uvnitř NSApplication.Init ()
metody. To je jeden z důvodů, proč je nutné volat první použití rozhraní COCOA API v Xamarin.Mac NSApplication.Init
.
Úloha registrarje informovat Objective-C modul runtime existence tříd jazyka C#aplikace, které pocházejí z tříd, jako NSApplicationDelegate
jsou , , NSView
NSWindow
a NSObject
. To vyžaduje kontrolu všech typů v aplikaci, aby bylo možné určit, co je potřeba zaregistrovat a jaké prvky jednotlivých typů pro sestavu.
Tuto kontrolu je možné provést dynamicky při spuštění aplikace s reflexí nebo staticky jako krok času sestavení. Při výběru typu registrace by měl vývojář vědět o těchto případech:
- Statická registrace může výrazně snížit dobu spuštění, ale může výrazně zpomalit časy sestavení (obvykle více než dvakrát ladit čas sestavení). Toto bude výchozí nastavení pro sestavení konfigurace vydaných verzí .
- Dynamická registrace tuto práci zpožďuje, dokud aplikace nespustí a přeskočí generování kódu, ale tato další práce může při spuštění aplikace vytvořit znatelnou pozastavení (alespoň dvě sekundy). To je obzvláště patrné v sestaveních konfigurace ladění, které se ve výchozím nastavení nastaví na dynamickou registraci a jejichž odraz je pomalejší.
Částečná statická registrace, která byla poprvé představena v Xamarin.iOS 8.13, poskytuje vývojářům nejlepší možnosti obou možností. Předpočítejte si registrační informace o všech elementech v Xamarin.Mac.dll
Xamarin.Mac ve statické knihovně (které je potřeba propojit jenom v době sestavení), Společnost Microsoft odebrala většinu času odrazu dynamického registrar času, aniž by to mělo vliv na čas sestavení.
Povolení částečné statické registrar
Částečná statická Registrar funkce je povolená v Xamarin.Mac poklikáním na název Project v Průzkumník řešení, přechodem na build Mac a přidáním --registrar:static
do pole Další argumenty mmp: Příklad:
Další materiály
Tady je několik podrobnějších vysvětlení toho, jak věci fungují interně: