Ste*_*uts 7 xamarin.ios mvvmcross xamarin
我试图在Link SDK only模式下使用MonoTouch编译我的iOS应用程序.如果我完全关闭链接它会完全编译,但它也产生一个巨大的二进制文件,不适合发布模式.
不幸的是,我需要的某个库以某种方式调用Expression.Visit,我无法弄清楚如何指示链接器不将其剥离.这会导致此编译错误:
错误MT2002:无法从"System.Core,Version = 2.0.5.0,Culture = neutral"解析"System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor :: Visit(System.Linq.Expressions.Expression)"引用,PublicKeyToken = 7cec85d7bea7798e"(MT2002)(MyApp)
根据自定义链接的文档,我设置了一个链接器文件来尝试阻止这种情况发生:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
</type>
</assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)
不幸的是,这没有任何影响 - 错误就像以前一样发生.
文档提到了preserve="fields"我可以提供的参数<type>,所以我尝试了:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor" preserve="methods" />
</assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)
那也行不通.
然后我在文件中引入了XML语法错误,并且构建失败,说它无法解析链接器文件,因此我至少知道正在读取该文件.
但后来我尝试在程序集名称中引入错误:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="NonexistentAssembly">
</assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)
这引起了一个错误,抱怨组装无法解决.
然后我试图破坏类型名称:
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="NonExistentType" preserve="methods" />
</assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)
现在,刚刚开始显示我之前看到的"无法解决表达式访问者::访问"错误.似乎没有检查类型名称.
此外,也不是签名名称,因为这也表示相同的编译错误.
<?xml version="1.0" encoding="UTF-8" ?>
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.ExpressionVisitor">
<method signature="jg98j23890rj2390erk90fk3ew!]['##'#'[" />
</type>
</assembly>
</linker>
Run Code Online (Sandbox Code Playgroud)
所以看起来只要指定程序集名称并具有有效的XML结构,链接器文件就不会引发任何异常.虽然链接器文件的文档对于这样一个复杂的主题并不特别冗长,但包含许多语法错误,即:
<type fullname="Foo" preserve="fields" />
<method name=".ctor" />
</type>
Run Code Online (Sandbox Code Playgroud)
此外,它没有提供链接器文件格式的技术说明,因此完全有可能我的定义完全错误.
我也尝试完全跳过System.Core的链接,--linkskip=System.Core但这没有效果.无论有没有,我都试过这个标志--xml.
在MvvmCross项目中,我尝试指定一个新类,以与LinkerPleaseInclude.cs文件相同的样式调用Visit方法,该文件由MvvmCross NuGet包添加到每个iOS项目中:
[Preserve]
public class PleaseIncludeVisitor : ExpressionVisitor
{
public PleaseIncludeVisitor()
{
this.Visit(null);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这也没有效果.
我目前正在使用Mono 3.2.6((no/9b58377)和Xamarin.iOS v7.0.7.2.
主要问题是在iOS上运行时无法进行代码生成.
这意味着,有很大一部分System.Linq.Expressions 会,通常情况下,是不可能在正常情况下提供(就像System.Refection.Emit不能提供).
为了解决这个问题,Xamarin.iOS一直在提供一种替代实现(可以解释最常见的表达式).
但是,当前代码与.NET框架不是100%API兼容(已修复但尚未发布).例如
System.Linq.Expressions.Expression System.Linq.Expressions.ExpressionVisitor::Visit(System.Linq.Expressions.Expression)
以上返回void当前的Xamarin.iOS(7.0.x)版本.这就是为什么链接器抱怨(它不是一个bug),因为它找不到这个成员引用(如果它找不到它就无法重新创建较小的,链接的程序集).无法保留不存在的成员(这就是您尝试使用XML文件或属性无效的原因).
在目前的解决办法是,以确认哪些组件使用这个API并重建(源文件)使用现有的System.Core.dll随机附带Xamarin.iOS.
笔记
我无法弄清楚如何指示链接器不将其剥离.
链接器不会尝试将其剥离它尝试保留它(即它必须加载引用才能将其保存回来).但是,它无法找到该成员,System.Core.dll因此无法提供有效的程序集链接版本.
Run Code Online (Sandbox Code Playgroud)<method signature="System.Linq.Expressions.Expression Visit(System.Linq.Expressions.Expression)" />
这要求保留不存在的东西.它将被忽略,即当void发现-reurning版本时,它将与XML描述不匹配.
| 归档时间: |
|
| 查看次数: |
1715 次 |
| 最近记录: |