2014-07-05 14 views
5

Ich versuche herauszufinden, was die Einschränkungen bei der Bereitstellung für iOS von Xamarin wirklich bedeutet.MakeGenericMethod/MakeGenericType auf Xamarin.iOS

http://developer.xamarin.com/guides/ios/advanced_topics/limitations/

Ich hatte den Eindruck, dass Sie keine JIT haben und somit jegliche Makegenericmethod oder Makegenerictype würde nicht funktionieren, dass würde JIT-Kompilierung erforderlich.

Auch habe ich verstanden, dass diese Einschränkungen nicht gelten, wenn der Simulator nicht im vollen AOT-Modus (Ahead of Time) läuft.

Nach dem Einrichten meines Mac, so dass ich auf meinem Telefon bereitstellen konnte, würde ich den folgenden Test fehlschlagen, wenn auf dem tatsächlichen Gerät (iPhone) ausgeführt wird.

Die Sache ist, dass erfolgreich abgeschlossen und ich kann nicht wirklich verstehen, warum. Erfordert dieser Code keine JIT-Kompilierung?

In dem Bemühen, "es zu brechen", habe ich auch einen Test mit MakeGenericType.

[Test] 
    public void InvokeGenericType() 
    { 
     var type = typeof(SomeGenericClass<>).MakeGenericType (typeof(string)); 

     var instance = Activator.CreateInstance (type); 

     var method = type.GetMethod ("Execute"); 

     method.Invoke (instance, new object[]{"Test"}); 

    } 


public class SomeGenericClass<T> 
{ 
    public void Execute(T value) 
    { 

    } 
} 

Wie kann das funktionieren, wenn es kein JIT gibt?

Fehle ich etwas?

+0

Dieser Code kann AOT kompiliert werden, so dass es ohne Probleme funktioniert. Wo Sie auf Einschränkungen stoßen, erzeugt IL-Code. Die Code-Generierung funktioniert unter Android und Windows Phone, nicht jedoch unter iOS. – SKall

+0

Nach diesem Artikel wird MakeGenericType bewirken, dass MSIL dynamisch generiert wird. http://msdn.microsoft.com/en-us/magazine/cc163610.aspx Wenn das wirklich der Fall ist, verstehe ich nicht, wie es funktionieren könnte. – seesharper

+0

Ich war eigentlich falsch, da der Code mit der aggressiven Verknüpfungsoption fehlschlagen wird (es sei denn, irgendwo anders im Code gibt es einen Verweis auf SomeGenericClass {string}). Siehe meine Antwort unten mit einem Beispielcode. – SKall

Antwort

2

Um den Code fehlzuschlagen gehen Sie zu iOS-Projektoptionen, Registerkarte "iOS Build" und ändern Sie das "Linker-Verhalten:" auf "Alle Baugruppen verknüpfen". Das Ausführen des Codes führt zu Exception und es wird vom Typ Standardkonstruktor für den Typ XXX gefunden, der nicht gefunden wurde.

Erstellen Sie nun einen Verweis auf die SomeGenericClass {Zeichenfolge} in Ihrem Code und die Methode wird problemlos ausgeführt. Die beiden hinzugefügten Zeilen bewirken, dass der Compiler SomeGenericClass {string} in die Binärdatei einfügt. Beachten Sie, dass die Zeilen überall in der Anwendung sein können, die in die Binärdatei kompiliert wird, sie müssen nicht in derselben Funktion sein.

public void InvokeGenericType() 
    { 
     // comment out the two lines below to make the code fail 
     var strClass = new SomeGenericClass<string>(); 
     strClass.Execute("Test"); 

     var type = typeof(SomeGenericClass<>).MakeGenericType (typeof(string)); 

     var instance = Activator.CreateInstance (type); 

     var method = type.GetMethod ("Execute"); 

     method.Invoke (instance, new object[]{"Test"}); 
    } 
+0

Also was Sie sagen, ist, dass, solange das Linker-Verhalten nicht auf "Alle Assemblies verknüpfen" festgelegt ist, MakeGenericType und MakeGenericMethod funktioniert? – seesharper

+1

Ja, da der Linker alle möglichen Kombinationen der generischen Klasse enthält. Dies kann zu einer großen Binärdatei führen, sodass eine Release-Version normalerweise empfohlen wird, die aggressive Verknüpfung zu verwenden. Mit den Standardeinstellungen würde ich denken, es würde fehlschlagen, wenn "SomeGenericClass" durch generische von den SDK-Bibliotheken ersetzt wurde. – SKall

Verwandte Themen