Udostępnij za pośrednictwem


Architektura platformy Xamarin.Mac

W tym przewodniku omówiono środowisko Xamarin.Mac i jego relacje na Objective-C niskim poziomie. Wyjaśniono w nim pojęcia, takie jak kompilacja, selektory, registrarsuruchamianie aplikacji i generator.

Omówienie

Aplikacje platformy Xamarin.Mac działają w środowisku wykonywania mono i używają kompilatora platformy Xamarin do kompilowania do języka pośredniego (IL), który jest następnie kompilowany just in time (JIT) do kodu natywnego w czasie wykonywania. Jest to uruchamiane obok środowiska uruchomieniowego Objective-C . Oba środowiska uruchomieniowe są uruchamiane na podstawie jądra przypominającego system UNIX, w szczególności XNU, i uwidaczniać różne interfejsy API dla kodu użytkownika, co umożliwia deweloperom dostęp do bazowego systemu natywnego lub zarządzanego.

Na poniższym diagramie przedstawiono podstawowe omówienie tej architektury:

Diagram showing a basic overview of the architecture

Kod natywny i zarządzany

Podczas programowania dla platformy Xamarin są często używane terminy natywne i zarządzane . Kod zarządzany to kod, który ma swoje wykonanie zarządzane przez środowisko uruchomieniowe języka wspólnego programu .NET Framework lub w przypadku platformy Xamarin: środowisko uruchomieniowe Mono.

Kod natywny to kod, który będzie uruchamiany natywnie na określonej platformie (na przykład lub Objective-C nawet skompilowany kod AOT na chipie ARM). W tym przewodniku opisano sposób kompilowania kodu zarządzanego do kodu natywnego i wyjaśniono, jak działa aplikacja Xamarin.Mac, umożliwiając pełne korzystanie z interfejsów API mac firmy Apple przy użyciu powiązań, a także dostęp do usługi . Lista BCL platformy NET i zaawansowany język, taki jak C#.

Wymagania

Do utworzenia aplikacji systemu macOS przy użyciu platformy Xamarin.Mac wymagane jest wykonanie następujących czynności:

  • Komputer Mac z systemem macOS Sierra (10.12) lub nowszym.
  • Najnowsza wersja środowiska Xcode (zainstalowana ze sklepu App Store)
  • Najnowsza wersja platformy Xamarin.Mac i Visual Studio dla komputerów Mac

Uruchamianie aplikacji dla komputerów Mac utworzonych za pomocą platformy Xamarin.Mac ma następujące wymagania systemowe:

  • Komputer Mac z systemem Mac OS X 10.7 lub nowszym.

Kompilacja

Podczas kompilowania dowolnej aplikacji platformy Xamarin kompilator Mono C# (lub F#) zostanie uruchomiony i skompiluje kod języka C# i F# w języku Microsoft Intermediate Language (MSIL lub IL). Następnie platforma Xamarin.Mac używa kompilatora just in time (JIT) w czasie wykonywania do kompilowania kodu natywnego, co umożliwia wykonywanie prawidłowej architektury zgodnie z potrzebami.

Jest to w przeciwieństwie do platformy Xamarin.iOS, która korzysta z kompilacji AOT. W przypadku korzystania z kompilatora AOT wszystkie zestawy i wszystkie metody w nich są kompilowane w czasie kompilacji. W przypadku trybu JIT kompilacja odbywa się na żądanie tylko dla wykonywanych metod.

W przypadku aplikacji platformy Xamarin.Mac mono jest zwykle osadzany w pakiecie aplikacji (i określanym jako Embedded Mono). W przypadku korzystania z klasycznego interfejsu API platformy Xamarin.Mac aplikacja może jednak używać interfejsu System Mono, jednak nie jest to obsługiwane w ujednoliconym interfejsie API. System Mono odnosi się do mono, który został zainstalowany w systemie operacyjnym. Po uruchomieniu aplikacji zostanie użyta aplikacja Xamarin.Mac.

Selektory

Dzięki platformie Xamarin mamy dwa oddzielne ekosystemy, .NET i Apple, które musimy połączyć, aby wydawać się tak usprawnione, jak to możliwe, aby zapewnić, że celem końcowym jest bezproblemowe środowisko użytkownika. W powyższej sekcji pokazano, jak dwa środowiska uruchomieniowe komunikują się, i być może bardzo dobrze znasz termin "powiązania", który umożliwia używanie natywnych interfejsów API mac na platformie Xamarin. Powiązania zostały szczegółowo wyjaśnione w Objective-C dokumentacji powiązania, więc na razie przyjrzyjmy się, jak działa platforma Xamarin.Mac pod maską.

Najpierw musi istnieć sposób uwidocznienia języka Objective-C C#, który odbywa się za pośrednictwem selektorów. Selektor to komunikat, który jest wysyłany do obiektu lub klasy. Dzięki Objective-C temu odbywa się za pośrednictwem funkcji objc_msgSend . Aby uzyskać więcej informacji na temat korzystania z selektorów, zapoznaj się z przewodnikiem selektorów systemu iOS.Objective-C Istnieje również sposób uwidocznienia kodu zarządzanego na Objective-Celement , co jest bardziej skomplikowane ze względu na fakt, że Objective-C nie wie nic o zarządzanym kodzie. Aby obejść ten błąd, użyjemy elementu registrar. Wyjaśniono to bardziej szczegółowo w następnej sekcji.

Registrar

Jak wspomniano powyżej, jest to registrar kod, który uwidacznia zarządzany kod w pliku Objective-C. W tym celu należy utworzyć listę każdej klasy zarządzanej pochodzącej z obiektu NSObject:

  • Dla wszystkich klas, które nie otaczają istniejącej Objective-C klasy, tworzy nową Objective-C klasę z elementami członkowskimi dublującym Objective-C wszystkie zarządzane elementy członkowskie, które mają [Export] atrybut.
  • W implementacjach każdego elementu członkowskiego Objective-C kod jest dodawany automatycznie w celu wywołania elementu członkowskiego zarządzanego przez dublowanie.

Poniższy kod przykładowy przedstawia przykład tego, jak to zrobić:

C# (kod zarządzany):

class MyViewController : UIViewController{
    [Export ("myFunc")]
    public void MyFunc ()
    {
    }
 }

Objective-C (kod natywny):

@interface MyViewController : UIViewController
 - (void)myFunc;
@end

@implementation MyViewController
- (void)myFunc {
    // Code to call the managed C# MyFunc method in MyViewController
}
@end

Kod zarządzany może zawierać atrybuty [Register] i [Export], których registrar używa, aby wiedzieć, że obiekt musi być uwidoczniony na Objective-C. Atrybut [Register] służy do określania nazwy wygenerowanej Objective-C klasy w przypadku, gdy domyślna wygenerowana nazwa nie jest odpowiednia. Wszystkie klasy pochodzące z obiektu NSObject są automatycznie rejestrowane za pomocą Objective-Cklasy . Wymagany atrybut [Export] zawiera ciąg, który jest selektorem używanym w wygenerowanej Objective-C klasie.

Istnieją dwa typy registrars używane na platformie Xamarin.Mac — dynamiczne i statyczne:

  • Dynamiczny registrars — jest to ustawienie domyślne registrar dla wszystkich kompilacji platformy Xamarin.Mac. Dynamiczna registrar funkcja wykonuje rejestrację wszystkich typów w zestawie w czasie wykonywania. Robi to przy użyciu funkcji udostępnianych przez Objective-Cinterfejs API środowiska uruchomieniowego. W związku z tym dynamika registrar ma wolniejsze uruchamianie, ale krótszy czas kompilacji. Funkcje natywne (zwykle w języku C), nazywane trampolinami, są używane jako implementacje metod podczas korzystania z dynamicznego registrarselementu . Różnią się one między różnymi architekturami.
  • Static registrars — statyczny registrarObjective-C generuje kod podczas kompilacji, który jest następnie kompilowany w bibliotece statycznej i połączony z plikiem wykonywalnym. Umożliwia to szybsze uruchamianie, ale trwa dłużej w czasie kompilacji.

Uruchamianie aplikacji

Logika uruchamiania platformy Xamarin.Mac różni się w zależności od tego, czy jest używany osadzony, czy system Mono. Aby wyświetlić kod i kroki uruchamiania aplikacji platformy Xamarin.Mac, zapoznaj się z plikiem nagłówka uruchamiania w publicznym repozytorium xamarin-macios.

Generator

Xamarin.Mac zawiera definicje dla każdego interfejsu API dla komputerów Mac. Możesz przeglądać dowolne z nich w repozytorium GitHub systemu MaciOS. Te definicje zawierają interfejsy z atrybutami, a także wszelkie niezbędne metody i właściwości. Na przykład następujący kod służy do definiowania NSBox w przestrzeni nazw AppKit. Zwróć uwagę, że jest to interfejs z wieloma metodami i właściwościami:

[BaseType (typeof (NSView))]
public interface NSBox {

    …

    [Export ("borderRect")]
    CGRect BorderRect { get; }

    [Export ("titleRect")]
    CGRect TitleRect { get; }

    [Export ("titleCell")]
    NSObject TitleCell { get; }

    [Export ("sizeToFit")]
    void SizeToFit ();

    [Export ("contentViewMargins")]
    CGSize ContentViewMargins { get; set; }

    [Export ("setFrameFromContentFrame:")]
    void SetFrameFromContentFrame (CGRect contentFrame);

    …

}

Generator o nazwie bmac w środowisku Xamarin.Mac pobiera te pliki definicji i używa narzędzi platformy .NET do kompilowania ich do zestawu tymczasowego. Jednak ten zestaw tymczasowy nie jest używany do wywoływania Objective-C kodu. Następnie generator odczytuje zestaw tymczasowy i generuje kod języka C#, który może być używany w czasie wykonywania. Dlatego na przykład jeśli dodasz losowy atrybut do pliku definicji .cs, nie będzie on wyświetlany w wyjściowym kodzie. Generator nie wie o tym i bmac dlatego nie wie, aby wyszukać go w zestawie tymczasowym, aby go wygenerować.

Po utworzeniu Xamarin.Mac.dll program packager mmppołączy wszystkie składniki razem.

Osiąga to na wysokim poziomie, wykonując następujące zadania:

  • Tworzenie struktury pakietu aplikacji.
  • Skopiuj do zarządzanych zestawów.
  • Jeśli łączenie jest włączone, uruchom zarządzany konsolidator, aby zoptymalizować zestawy, usuwając nieużywane części.
  • Utwórz aplikację uruchamiania, łącząc w kodzie uruchamiania omówionym razem z registrar kodem, jeśli jest w trybie statycznym.

Jest to następnie uruchamiane w ramach procesu kompilacji użytkownika, który kompiluje kod użytkownika do zestawu, który odwołuje się Xamarin.Mac.dll i uruchamia mmp go, aby utworzyć pakiet

Aby uzyskać bardziej szczegółowe informacje na temat konsolidatora i sposobu jego użycia, zapoznaj się z przewodnikiem konsolidatora systemu iOS.

Podsumowanie

W tym przewodniku przedstawiono kompilację aplikacji platformy Xamarin.Mac oraz zapoznano się z platformą Xamarin.Mac i jego relacją z platformą Objective-C.