JIT error with LINQ OrderBy using C# on iOS

懵懂的女人 提交于 2019-12-23 08:53:57

问题


I'm receiving the following error on my iOS device:

ExecutionEngineException: Attempting to JIT compile method 'System.Linq.OrderedEnumerable1<System.Collections.Generic.KeyValuePair2>:GetEnumerator ()' while running with --aot-only.

I'm using Unity3D, and I know the error is caused because LINQ expressions have issues with ordering value types when compiling Unity to iOS. Because (I think) that the expression attempts to use reflection to instantiate a new type which implements the IComparer<TKey> interface. This will work for reference types, but not value types on a Unity iOS build.

So my thought was that since I know in this situation I'm always trying to order a collection of ints. That I could bypass the generic ICompare<TKey> and just create my own custom comparer.

public class IntCompare : Comparer<int> {

    public override int Compare (int x, int y)
    {
       return x - y;
    }
}

However, using OrderBy still gives me the error. Is there something I'm not understanding on why my method doesn't work?

My expression:

OptimizeMaxCommitList(members
                            .OrderBy((memberid) => memberid.Value, new IntCompare())
                            .Skip(1)
                            .ToDictionary(pair => pair.Key, pair => pair.Value)
                    ,maxCommit);

回答1:


Most of LINQ extension methods from LINQ for Collections are not working with IEnumerables on iOS since they require the AOT runtime compiler which is not supported.

However there is a LINQ for iOS library on Asset Store that is similar to LINQ, but doesn't require a runtime compiler. So you can use it on iOS.




回答2:


By the way, your comparison is broken.

Reading return (x < y) ? x : y; you are returning the smallest of the integers, however a comparer is to provide the result of comparing two objects (read: objects as anything you handle, be it int, bool or string).

Quoting MSDN, a comparison's return value is defined as:

  • Less than zero: x is less than y.
  • Zero: x equals y.
  • Greater than zero: x is greater than y.

...were x is the first parameter.

Thus your comparison should read return x - y; or the sorting algorithm will never terminate with correct results (although it will detect too many iterations and throw an exception complaining that the comparison is broken).




回答3:


This doesn't answer my question directly, but I found a workaround using,

members = sortDictionary(members);
OptimizeMaxCommitList(members
                          .Skip(1)
                          .ToDictionary(pair => pair.Key, pair => pair.Value),
                      maxCommit);

private Dictionary<string, int> sortDictionary(Dictionary<string, int> members)
{
    List<KeyValuePair<string, int>> list = members.ToList();

    list.Sort((firstPair,nextPair) =>
        {
            return firstPair.Value.CompareTo(nextPair.Value);
        }
    );

    return list.ToDictionary((keyItem) => keyItem.Key, (valueItem) => valueItem.Value);
}


来源:https://stackoverflow.com/questions/16485517/jit-error-with-linq-orderby-using-c-sharp-on-ios

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!