Łączenie aplikacji platformy Xamarin.iOS

Podczas kompilowania aplikacji Visual Studio dla komputerów Mac lub Visual Studio wywołuje narzędzie o nazwie mtouch, które zawiera konsolidator kodu zarządzanego. Służy do usuwania z bibliotek klas funkcji, których aplikacja nie używa. Celem jest zmniejszenie rozmiaru aplikacji, która będzie dostarczana tylko z wymaganymi bitami.

Konsolidator używa analizy statycznej do określania różnych ścieżek kodu, które aplikacja jest podatna na obserwowanie. Jest to nieco ciężkie, ponieważ musi przejść przez wszystkie szczegóły każdego zestawu, aby upewnić się, że nic nie można odnaleźć nie zostanie usunięte. Nie jest ona domyślnie włączona w kompilacjach symulatora, aby przyspieszyć czas kompilacji podczas debugowania. Jednak ponieważ tworzy mniejsze aplikacje, może przyspieszyć kompilację IOT i przekazać do urządzenia, wszystkie urządzenia (wydanie) kompilacje domyślnie używają konsolidatora.

Ponieważ konsolidator jest narzędziem statycznym, nie może oznaczać typów i metod dołączania, które są wywoływane przez odbicie lub dynamicznie tworzone wystąpienia. Istnieje kilka opcji obejścia tego ograniczenia.

Zachowanie konsolidatora

Proces łączenia można dostosować za pomocą listy rozwijanej zachowanie konsolidatora w obszarze Opcje projektu. Aby uzyskać dostęp do tego dwukrotnego kliknięcia projektu systemu iOS i przejdź do opcji konsolidatora kompilacji > systemu iOS, jak pokazano poniżej:

Linker Options

Poniżej opisano trzy główne opcje:

Wyłączenie łączenia gwarantuje, że żadne zestawy nie są modyfikowane. Ze względu na wydajność jest to ustawienie domyślne, gdy obiekty docelowe środowiska IDE dla symulatora systemu iOS. W przypadku urządzeń kompilowanie tej funkcji powinno być używane tylko jako obejście za każdym razem, gdy konsolidator zawiera usterkę uniemożliwiającą uruchomienie aplikacji. Jeśli aplikacja działa tylko z parametrem -nolink, prześlij raport o usterce.

Odpowiada to opcji -nolink podczas korzystania z narzędzia wiersza polecenia mtouch.

W tym trybie konsolidator pozostawi zestawy nietknięte i zmniejszy rozmiar zestawów SDK (tj. elementów dostarczanych z platformą Xamarin.iOS), usuwając wszystko, czego nie używa aplikacja. Jest to ustawienie domyślne, gdy środowisko IDE jest przeznaczone dla urządzeń z systemem iOS.

Jest to najprostsza opcja, ponieważ nie wymaga ona żadnych zmian w kodzie. Różnica w łączeniu wszystkiego polega na tym, że konsolidator nie może wykonać kilku optymalizacji w tym trybie, więc jest to kompromis między pracą wymaganą do połączenia wszystkiego i końcowego rozmiaru aplikacji.

Odpowiada to opcji -linksdk podczas korzystania z narzędzia wiersza polecenia mtouch.

Łącząc wszystko, konsolidator może używać całego zestawu jego optymalizacji, aby aplikacja była jak najmniejsza. Spowoduje to zmodyfikowanie kodu użytkownika, co może spowodować przerwanie za każdym razem, gdy kod używa funkcji w sposób, który nie może wykryć analizy statycznej konsolidatora. W takich przypadkach, np. usługi internetowe, odbicie lub serializacja, niektóre dostosowania mogą być wymagane w aplikacji, aby połączyć wszystko.

Odpowiada to opcji -linkall podczas korzystania z narzędzia wiersza polecenia mtouch.

Kontrolowanie konsolidatora

Gdy używasz konsolidatora, czasami usuniesz kod, który mógł być wywoływany dynamicznie, nawet pośrednio. Aby uwzględnić te przypadki, konsolidator udostępnia kilka funkcji i opcji, aby umożliwić większą kontrolę nad jego akcjami.

Zachowywanie kodu

Gdy używasz konsolidatora, czasami można usunąć kod, który może być wywoływany dynamicznie przy użyciu systemu. Emocje ion. MemberInfo.Invoke lub przez wyeksportowanie metod do Objective-C przy użyciu atrybutu[Export], a następnie wywołanie selektora ręcznie.

W takich przypadkach można poinstruować konsolidatora, aby rozważył użycie całych klas lub pojedynczych składowych do zachowania przez zastosowanie atrybutu [Xamarin.iOS.Foundation.Preserve] na poziomie klasy lub na poziomie elementu członkowskiego. Każdy element członkowski, który nie jest statycznie połączony przez aplikację, podlega usunięciu. Ten atrybut jest zatem używany do oznaczania elementów członkowskich, do których nie odwołuje się statycznie, ale które są nadal potrzebne przez aplikację.

Na przykład w przypadku dynamicznego tworzenia wystąpień typów możesz zachować domyślny konstruktor typów. Jeśli używasz serializacji XML, możesz zachować właściwości typów.

Ten atrybut można zastosować na każdym elemencie typu lub na samym typie. Jeśli chcesz zachować cały typ, możesz użyć składni [Preserve (AllMembers = true)] w typie.

Czasami chcesz zachować niektóre elementy członkowskie, ale tylko wtedy, gdy typ zawierający został zachowany. W takich przypadkach należy użyć polecenia [Preserve (Conditional=true)]

Jeśli nie chcesz stosować zależności od bibliotek platformy Xamarin — na przykład załóżmy, że tworzysz międzyplatformową przenośną bibliotekę klas (PCL) — nadal możesz użyć tego atrybutu.

W tym celu należy zadeklarować klasę PreserveAttribute i użyć jej w kodzie w następujący sposób:

public sealed class PreserveAttribute : System.Attribute {
    public bool AllMembers;
    public bool Conditional;
}

Nie ma znaczenia, w której przestrzeni nazw jest zdefiniowana, konsolidator szuka tego atrybutu według nazwy typu.

Pomijanie zestawów

Istnieje możliwość określenia zestawów, które powinny zostać wykluczone z procesu konsolidatora, przy jednoczesnym umożliwieniu normalnego łączenia innych zestawów. Jest to przydatne, jeśli użycie [Preserve] niektórych zestawów jest niemożliwe (np. kod innej firmy) lub jako tymczasowe obejście błędu.

--linkskip Odpowiada to opcji podczas korzystania z narzędzia wiersza polecenia mtouch.

Jeśli używasz opcji Połącz wszystkie zestawy , jeśli chcesz poinformować konsolidatora o pomijaniu całych zestawów, umieść następujące elementy w opcjach Dodatkowe argumenty mtouch zestawu najwyższego poziomu:

--linkskip=NameOfAssemblyToSkipWithoutFileExtension

Jeśli chcesz, aby konsolidator pominął wiele zestawów, dołącz wiele linkskip argumentów:

--linkskip=NameOfFirstAssembly --linkskip=NameOfSecondAssembly

Nie ma interfejsu użytkownika do używania tej opcji, ale można ją udostępnić w oknie dialogowym Visual Studio dla komputerów Mac Opcje projektu lub w okienku Właściwości projektu programu Visual Studio w polu tekstowym Dodatkowe argumenty mtouch. (Np. --linkskip=mscorlib nie łączyłby mscorlib.dll, ale łączyłby inne zestawy w rozwiązaniu).

Konsolidator usunie kod, który jest bardzo mało prawdopodobne, aby był używany na urządzeniach, np. nieobsługiwane lub niedozwolone. W rzadkich przypadkach istnieje możliwość, że aplikacja lub biblioteka zależy od tego (działającego lub nie) kodu. Ponieważ Xamarin.iOS 5.0.1 można poinstruować konsolidator, aby pominąć tę optymalizację.

Odpowiada to opcji -nolinkaway podczas korzystania z narzędzia wiersza polecenia mtouch.

Nie ma interfejsu użytkownika do używania tej opcji, ale można ją udostępnić w oknie dialogowym Visual Studio dla komputerów Mac Opcje projektu lub w okienku Właściwości projektu programu Visual Studio w polu tekstowym Dodatkowe argumenty mtouch. (Np. --nolinkaway nie spowoduje usunięcia dodatkowego kodu (około 100 kb)).

Oznaczanie zestawu jako gotowego konsolidatora

Użytkownicy mogą po prostu połączyć zestawy SDK i nie łączyć się z ich kodem. Oznacza to również, że wszystkie biblioteki innych firm, które nie są częścią podstawowego zestawu SDK platformy Xamarin, nie będą połączone.

Dzieje się tak zazwyczaj, ponieważ nie chcą ręcznie dodawać [Preserve] atrybutów do kodu. Efektem ubocznym jest to, że biblioteki innych firm nie będą połączone, a ogólnie jest to dobre ustawienie domyślne, ponieważ nie można wiedzieć, czy biblioteka innej firmy jest przyjazna, czy nie.

Jeśli masz bibliotekę w projekcie lub jesteś deweloperem bibliotek wielokrotnego użytku i chcesz, aby konsolidator traktować zestaw jako linkable, wystarczy dodać atrybut LinkerSafena poziomie zestawu , jak pokazano poniżej:

[assembly:LinkerSafe]

Biblioteka nie musi w rzeczywistości odwoływać się do bibliotek platformy Xamarin w tym celu. Jeśli na przykład tworzysz przenośną bibliotekę klas, która będzie działać na innych platformach, nadal możesz użyć atrybutu LinkerSafe . Konsolidator Xamarin wyszukuje LinkerSafe atrybut według nazwy, a nie według rzeczywistego typu. Oznacza to, że można napisać ten kod i będzie również działać:

[assembly:LinkerSafe]
// ... assembly attribute should be at top, before source
class LinkerSafeAttribute : System.Attribute {}

Konfiguracja konsolidatora niestandardowego

Postępuj zgodnie z instrukcjami dotyczącymi tworzenia pliku konfiguracji konsolidatora.