Бөлісу құралы:


Архитектура Xamarin.Mac

В этом руководстве рассматриваются Xamarin.Mac и его отношения с Objective-C низким уровнем. В нем описываются такие понятия, как компиляция, селекторы, registrarsзапуск приложения и генератор.

Обзор

Приложения Xamarin.Mac выполняются в среде выполнения Mono и используют компилятор Xamarin для компиляции на промежуточный язык (IL), который затем jIT-код компилируется в машинный код во время выполнения. Это выполняется параллельно со средой Objective-C выполнения. Обе среды выполнения выполняются поверх ядра UNIX, например XNU, и предоставляют различные API-интерфейсы пользовательскому коду, позволяя разработчикам получать доступ к базовой собственной или управляемой системе.

На следующей схеме показан базовый обзор этой архитектуры:

Diagram showing a basic overview of the architecture

Собственный и управляемый код

При разработке для Xamarin часто используются собственныйи управляемый код. Управляемый код — это код, который управляется платформа .NET Framework средой CLR или в случае Xamarin: среда выполнения Mono.

Машинный код — это код, который будет выполняться в собственном коде на конкретной платформе (например, Objective-C или даже скомпилированный код AOT на микросхеме ARM). В этом руководстве описывается, как скомпилированный управляемый код компилируется в машинный код и объясняется, как работает приложение Xamarin.Mac, что обеспечивает полный доступ к API Apple Для Mac с помощью привязок, а также имеет доступ к . BCL NET и сложный язык, например C#.

Требования

Для разработки приложения macOS с помощью Xamarin.Mac macOS требуется следующее:

  • Mac под управлением macOS Sierra (10.12) или более поздней версии.
  • Последняя версия Xcode (установленная из App Store)
  • Последняя версия Xamarin.Mac и Visual Studio для Mac

Для запуска приложений Mac, созданных с помощью Xamarin.Mac, необходимо выполнить следующие системные требования:

  • Mac под управлением Mac OS X 10.7 или более поздней версии.

табличных переменных

При компиляции любого приложения платформы Xamarin компилятор Mono C# (или F#) будет выполняться и компилирует код C# и F# на промежуточный язык Майкрософт (MSIL или IL). Затем Xamarin.Mac использует компилятор JIT во время выполнения для компиляции машинного кода, разрешая выполнение в правильной архитектуре по мере необходимости.

Это отличается от Xamarin.iOS, использующего компиляцию AOT. При использовании компилятора AOT все сборки и все методы в них компилируются во время сборки. При JIT компиляция выполняется только по запросу только для выполняемых методов.

При использовании приложений Xamarin.Mac Mono обычно внедряется в пакет приложений (и называется Embedded Mono). При использовании классического API Xamarin.Mac приложение может вместо этого использовать System Mono, однако это не поддерживается в едином API. System Mono относится к Mono, который был установлен в операционной системе. При запуске приложения приложение Xamarin.Mac будет использовать это.

Селекторы

С Xamarin у нас есть две отдельные экосистемы, .NET и Apple, что нам нужно объединить, чтобы показаться как можно более упрощенным, чтобы гарантировать, что конечная цель является гладким взаимодействием с пользователем. Мы видели в разделе выше, как два среды выполнения взаимодействуют, и вы, возможно, очень хорошо слышали о термине "привязки", который позволяет использовать собственные API Mac в Xamarin. Привязки подробно описаны в Objective-C документации по привязке, поэтому теперь давайте рассмотрим, как работает Xamarin.Mac под капюшоном.

Во-первых, существует способ предоставления Objective-C доступа к C#, который выполняется с помощью селекторов. Селектор — это сообщение, которое отправляется в объект или класс. При Objective-C этом выполняется с помощью функций objc_msgSend . Дополнительные сведения об использовании селекторов см. в руководстве по селекторам iOS.Objective-C Существует также способ предоставления управляемого кода Objective-C, который является более сложным из-за того, что Objective-C ничего не известно об управляемом коде. Чтобы обойти это, мы используем registrar. Более подробно описано в следующем разделе.

Registrar

Как упоминание выше, это registrar код, предоставляющий управляемый кодObjective-C. Это делается путем создания списка каждого управляемого класса, наследуемого от NSObject:

  • Для всех классов, которые не упаковывают существующий Objective-C класс, он создает новый Objective-C класс с Objective-C элементами, зеркало со всеми управляемыми элементами, имеющими [Export] атрибут.
  • В реализациях для каждого члена Objective–C код добавляется автоматически для вызова зеркало управляемого члена.

В приведенном ниже псевдокоде показано, как это сделать:

C# (управляемый код):

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

Objective-C (машинный код):

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

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

Управляемый код может содержать атрибуты и [Register][Export], что registrar используется для того, чтобы знать, что объекту необходимо предоставить Objective-Cдоступ. Атрибут [Register] используется для указания имени созданного Objective-C класса в случае, если созданное по умолчанию имя не подходит. Все классы, производные от NSObject, автоматически регистрируются в Objective-C. Обязательный атрибут [Export] содержит строку, которая является селектором, используемым в созданном Objective-C классе.

В Xamarin.Mac используется два типа: динамический и статический registrars :

  • Dynamic registrars — это значение по умолчанию registrar для всех сборок Xamarin.Mac. registrar Dynamic выполняет регистрацию всех типов в сборке во время выполнения. Это делается с помощью функций, предоставляемых Objective-CAPI среды выполнения. Следовательно, динамический registrar имеет более медленный запуск, но более быстрое время сборки. Собственные функции (обычно в C), называемые батутами, используются в качестве реализаций методов при использовании динамической registrars. Они различаются между различными архитектурами.
  • Статический — статический registrarsregistrar создает Objective-C код во время сборки, который затем компилируется в статическую библиотеку и связан с исполняемым файлом. Это позволяет ускорить запуск, но занимает больше времени во время сборки.

Запуск приложения

Логика запуска Xamarin.Mac будет отличаться в зависимости от того, используется ли внедренный или системный Mono. Чтобы просмотреть код и шаги запуска приложения Xamarin.Mac, обратитесь к файлу заголовка запуска в общедоступном репозитории xamarin-macios.

Генератор

Xamarin.Mac содержит определения для каждого API Mac. Вы можете просмотреть любой из них в репозитории GitHub MaciOS. Эти определения содержат интерфейсы с атрибутами, а также любые необходимые методы и свойства. Например, следующий код используется для определения NSBox в пространстве имен AppKit. Обратите внимание, что это интерфейс с рядом методов и свойств:

[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);

    …

}

Генератор, который вызывается bmac в Xamarin.Mac, принимает эти файлы определения и использует средства .NET для компиляции их во временную сборку. Однако эта временная сборка не используется для вызова Objective-C кода. Затем генератор считывает временную сборку и создает код C#, который можно использовать во время выполнения. Поэтому, например, если добавить случайный атрибут в файл определения .cs, он не будет отображаться в выходном коде. Генератор не знает об этом, поэтому bmac не знает, чтобы искать его во временной сборке, чтобы вывести его.

После создания Xamarin.Mac.dll упаковщик mmpсоединит все компоненты вместе.

На высоком уровне это достигается путем выполнения следующих задач:

  • Создайте структуру пакета приложений.
  • Скопируйте в управляемые сборки.
  • Если связывание включено, запустите управляемый компоновщик для оптимизации сборок, удалив неиспользуемые части.
  • Создайте приложение средства запуска, связывание в коде средства запуска, о котором говорилось вместе с registrar кодом, если в статичном режиме.

Затем он запускается как часть процесса сборки пользователя, который компилирует пользовательский код в сборку, которая ссылается на Xamarin.Mac.dll и выполняется mmp , чтобы сделать его пакетом

Дополнительные сведения об компоновщике и его использовании см. в руководстве по компоновщику iOS.

Итоги

В этом руководстве рассматриваются компиляции приложений Xamarin.Mac и рассматриваются Xamarin.Mac и его отношения Objective-Cс .