我正在尝试运行Windows Azure移动服务查询(使用SDK的xamarins monotouch fork)。
这段代码在模拟器上运行良好,但在设备上就会崩溃:
this.table.Where (a => a.Sequence == sequence).Where (a => a.Week == week).ToListAsync()
.ContinueWith (t =>
{
this.items = t.Result;
this.tableView.ReloadData ();
IsUpdating = false;
}, scheduler);
我得到的错误是:
异常被调用的目标抛出。--->系统。异常:尝试JIT编译方法"System.Linq.jvm。运行时调用GetDelegate ()——aot-only。
我唯一能做的就是移除where条件。这工作得很好,除了我(显然)没有得到结果过滤的需要。
我应该如何重写我的代码,使其在实际的iOS设备上工作?
更新:table是一个类型为*IMobileServiceTable <活动> *活动>
week和sequence都是类型int。
Activity是一个POCO类。
public class Activity
{
public int ID {
get;
set;
}
public string Name {
get;
set;
}
public int CaloricRequirementMin {
get;
set;
}
public int CaloricRequirementMax {
get;
set;
}
public string Difficulty {
get;
set;
}
public int PlanId {get;set;}
public string Type {
get;
set;
}
public int Sequence {
get;
set;
}
public int Week {
get;
set;
}
public int SubscriptionActivityId {
get;
set;
}
}
我已经仔细检查了,以确保这些都是填充的。
它在模拟器上完美地显示
MonoTouch Ahead of Time (AOT)编译器的全部意义在于避免苹果不允许在iOS中编译的问题。这是几种安全策略之一,还有签名可执行文件、应用程序审查、沙箱等。不幸的是,某些LINQ表达式需要JIT编译,因此不能在设备上运行。
所有LINQ表达式都可以转换为非LINQ,通常是迭代的代码。在转换为迭代之前,您可以考虑一些可能有效的LINQ替代方案,例如Any()表达式。
最后,我不得不修改我的代码,使用ReadAsync和字符串查询,而不是linq表达式。
this.table.ReadAsync(query)
.ContinueWith (t =>
{
items = (from item in t.Result.GetArray()
let act = item.GetObject()
select new Activity{
ID= Convert.ToInt32(act.GetNamedNumber("id")),
Name= act.GetNamedString("Name"),
SubscriptionActivityId = act.ContainsKey("SubscriptionActivityId") ? Convert.ToInt32(act.GetNamedNumber("SubscriptionActivityId")) : 0
}).ToList();
this.tableView.ReloadData ();
IsUpdating = false;
}, scheduler);