Arquitectura de Xamarin.Mac
En esta guía se explora Xamarin.Mac y su relación Objective-C con en un nivel bajo. En él se explican conceptos como la compilación, los selectores, registrars el inicio de la aplicación y el generador.
Información general
Las aplicaciones de Xamarin.Mac se ejecutan en el entorno de ejecución mono y usan el compilador de Xamarin para compilar en lenguaje intermedio (IL), que luego se compila Just-In-Time (JIT) en código nativo en tiempo de ejecución. Esto se ejecuta en paralelo con Objective-C runtime. Ambos entornos en tiempo de ejecución se ejecutan sobre un kernel de tipo UNIX, específicamente XNU, y exponen varias API al código de usuario, lo que permite a los desarrolladores acceder al sistema nativo o administrado subyacente.
En el diagrama siguiente se muestra una introducción básica de esta arquitectura:
que muestra una introducción básica de la
Código nativo y administrado
Al desarrollar para Xamarin, a menudo se usan los términos código nativo y administrado. El código administrado es código que tiene su ejecución administrada por el .NET Framework Common Language Runtime o, en el caso de Xamarin: Mono Runtime.
El código nativo es código que se ejecutará de forma nativa en la plataforma específica (por ejemplo, o incluso código compilado por Objective-C AOT, en un chip arm). En esta guía se explora cómo se compila el código administrado en código nativo y se explica cómo funciona una aplicación de Xamarin.Mac, haciendo un uso completo de las API de Mac de Apple mediante el uso de enlaces, a la vez que se tiene acceso a . BCL de NET y un lenguaje sofisticado como C#.
Requisitos
Para desarrollar una aplicación maOS con Xamarin.Mac, se requiere lo siguiente:
- Un equipo Mac macOS Sierra (10.12) o superior.
- La versión más reciente de Xcode (instalada desde la App Store)
- La versión más reciente de Xamarin.Mac y Visual Studio para Mac
La ejecución de aplicaciones de Mac creadas con Xamarin.Mac tiene los siguientes requisitos del sistema:
- Un equipo Mac Mac OS X 10.7 o superior.
Compilación
Al compilar cualquier aplicación de plataforma Xamarin, el compilador mono C# (o F#) se ejecutará y compilará el código de C# y F# en lenguaje intermedio de Microsoft (MSIL o IL). A continuación, Xamarin.Mac usa un compilador Just-In-Time (JIT) en tiempo de ejecución para compilar código nativo, lo que permite la ejecución en la arquitectura correcta según sea necesario.
Esto contrasta con Xamarin.iOS, que usa la compilación de AOT. Cuando se usa el compilador de AOT, todos los ensamblados y todos los métodos dentro de ellos se compilan en tiempo de compilación. Con JIT, la compilación solo se produce a petición para los métodos que se ejecutan.
Con las aplicaciones de Xamarin.Mac, Mono normalmente se inserta en el paquete de aplicaciones (y se conoce como Mono incrustado). Al usar la API clásica de Xamarin.Mac, la aplicación podría usar System Mono,pero esto no se admite en el Unified API. System Mono hace referencia a Mono que se ha instalado en el sistema operativo. Al iniciar la aplicación, la aplicación Xamarin.Mac lo usará.
Selectores
Con Xamarin, tenemos dos ecosistemas independientes, .NET y Apple, que necesitamos reunir para parecer lo más simplificado posible, para garantizar que el objetivo final sea una experiencia de usuario fluida. Hemos visto en la sección anterior cómo se comunican los dos entornos de ejecución y es posible que haya oído hablar del término "enlaces", que permite usar las API nativas de Mac en Xamarin. Los enlaces se explican en profundidad en , por lo que, por ahora, vamos a explorar cómo Objective-C binding documentation funciona Xamarin.Mac en el fondo.
En primer lugar, debe haber una manera de exponer Objective-C a C#, que se realiza a través de selectores. Un selector es un mensaje que se envía a un objeto o clase. Esto Objective-C se hace a través de las Objective-C de trabajo. Para obtener más información sobre el uso de selectores, consulte la guía de Objective-C Selectors iOS. También debe haber una manera de exponer el código administrado a , que es más complicado debido al hecho de que no sabe Objective-C nada sobre el código Objective-C administrado. Para evitarlo, usamos un registrador " data-linktype="relative-path">registrar . Esto se explica con más detalle en la sección siguiente.
Registrar
Como se mencionó anteriormente, registrar es el código que expone código administrado a Objective-C . Para ello, crea una lista de todas las clases administradas que se derivan de NSObject:
- Para todas las clases que no encapsulan una clase existente, crea una nueva clase con miembros que reflejan todos los miembros administrados Objective-C que tienen un atributo Objective-CObjective-C
[Export]. - En las implementaciones de cada miembro de Objective–C, el código se agrega automáticamente para llamar al miembro administrado reflejado.
El pseudocódigo siguiente muestra un ejemplo de cómo se hace esto:
C# (código administrado):
class MyViewController : UIViewController{
[Export ("myFunc")]
public void MyFunc ()
{
}
}
(código nativo):
@interface MyViewController : UIViewController
- (void)myFunc;
@end
@implementation MyViewController
- (void)myFunc {
// Code to call the managed C# MyFunc method in MyViewController
}
@end
El código administrado puede contener los atributos y , que utiliza para saber [Register] que el objeto debe [Export]registrar exponerse a Objective-C . El atributo [Register] se usa para especificar el nombre de la clase generada en caso de que el Objective-C nombre generado predeterminado no sea adecuado. Todas las clases derivadas de NSObject se registran automáticamente con Objective-C . El atributo [Export] necesario contiene una cadena, que es el selector usado en la clase Objective-C generada.
Hay dos tipos de registrars usados en Xamarin.Mac: dinámico y estático:
- Dinámico: registrars este es el valor predeterminado para todas las registrar compilaciones de Xamarin.Mac. La dinámica registrar realiza el registro de todos los tipos en el ensamblado en tiempo de ejecución. Para ello, usa las funciones proporcionadas por la API en tiempo Objective-C de ejecución de . Por lo registrar tanto, la dinámica tiene un inicio más lento, pero un tiempo de compilación más rápido. Las funciones nativas (normalmente en C), denominadas "colines", se usan como implementaciones de método cuando se usa el dinámico registrars . Varían entre distintas arquitecturas.
- Static: registrars el estático genera código durante la compilación, que luego se compila en una biblioteca estática registrar y se vincula al archivo Objective-C ejecutable. Esto permite un inicio más rápido, pero tarda más tiempo durante el tiempo de compilación.
Inicio de la aplicación
La lógica de inicio de Xamarin.Mac variará en función de si se usa Mono insertado o del sistema. Para ver el código y los pasos para el inicio de la aplicación Xamarin.Mac, consulte el archivo de encabezado launch en el repositorio público xamarin-macios.
Generator
Xamarin.Mac contiene definiciones para cada API de Mac. Puede examinar cualquiera de ellos en el repositorio de GitHub de MaciOS. Estas definiciones contienen interfaces con atributos, así como los métodos y propiedades necesarios. Por ejemplo, el código siguiente se usa para definir un NSBox en el espacio de nombres de AppKit. Observe que se trata de una interfaz con una serie de métodos y propiedades:
[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);
…
}
El generador, denominado en Xamarin.Mac, toma estos archivos de definición y usa herramientas bmac de .NET para compilarlos en un ensamblado temporal. Sin embargo, este ensamblado temporal no se puede usar para llamar al Objective-C código. A continuación, el generador lee el ensamblado temporal y genera código de C# que se puede usar en tiempo de ejecución. Por este motivo, por ejemplo, si agrega un atributo aleatorio al archivo .cs de definición, no se mostrará en el código de salida. El generador no lo sabe y, por lo tanto, no sabe buscarlo en el bmac ensamblado temporal para generarlo.
Una vez Xamarin.Mac.dll se ha creado el paqueter, mmp , agrupará todos los componentes.
En un nivel alto, lo consigue mediante la ejecución de las siguientes tareas:
- Cree una estructura de agrupación de aplicaciones.
- Copie en los ensamblados administrados.
- Si la vinculación está habilitada, ejecute el vinculador administrado para optimizar los ensamblados quitando los elementos no usados.
- Cree una aplicación de iniciador, vinculando en el código del iniciador al que se ha hablado junto con el registrar código si está en modo estático.
A continuación, se ejecuta como parte del proceso de compilación de usuario que compila el código de usuario en un ensamblado que hace referencia a la Xamarin.Mac.dll y se ejecuta para convertirla mmp en un paquete.
Para obtener información más detallada sobre el vinculador y cómo se usa, consulte la guía del vinculador de iOS.
Resumen
En esta guía se ha visto la compilación de aplicaciones de Xamarin.Mac y se ha explorado Xamarin.Mac y su relación con Objective-C .