我感到困惑的一些反射代码,并寻找洞察力
-
19-09-2019 - |
题
我使用C#和Mono的全AOT技术为iPhone开发。根据他们的限制的页面(链接文本),不像传统的单声道/。 NET,在iPhone代码被静态编译时间提前,而不是在由JIT编译器的需求正在编译。
当在硬件上运行时,发生以下情况例外:
ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Image, UnityEngine.Color> (System.Reflection.MonoProperty/Getter`2<Image, UnityEngine.Color>,object)' while running with --aot-only.
System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000]
Ani+AniValue.Get ()
Ani.CreateAnimations (System.Object obj, System.Collections.Hashtable properties, Single duration, System.Collections.Hashtable options, AniType type)
Ani.Method (AniType type, System.Object obj, Single duration, System.Collections.Hashtable _properties, System.Collections.Hashtable _options)
Ani.From (System.Object obj, Single duration, System.Collections.Hashtable _properties)
xObject+<>c__CompilerGenerated5.MoveNext ()
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
xObject:StartAnimation(Animate, GameObject, Object, Object)
SceneSplash:CreateBackground()
SceneSplash:OnSetup()
SceneSplash:OnSceneActivate(Callback)
GameController:ActivateScene()
GameController:DeactivateScene()
GameController:SceneLoaded(Scene, GameObject, SceneBase)
SceneBase:Start()
根据该限制文件,System.Reflection.Emit不被支持,但他们指出,从Reflection.Emit的侧“的整个反射API,包括Type.GetType(” SomeClass的“),列出的方法,列出的属性,获取属性和值工作得很好。“
我包含引起该异常的代码...
void CreateAnimations(System.Object obj, Hashtable properties, float duration,
Hashtable options, AniType type)
{
foreach (DictionaryEntry item in properties)
{
name = (string)item.Key; // Extract name and value
System.Object value = item.Value;
AniValue foo = new AniValue(obj, name); // Create value object
/* To exception occurs inside Get() */
System.Object current = foo.Get(); // Get current value
...
在上面的方法从哈希表抓起属性名称,并使用它(与物镜一起)来创建AniValue的一个实例。只是后来,foo.Get()被调用来检索属性的值。上propertyInfo.GetValue发生异常(OBJ,空)。
using System.Reflection
public class AniValue
{
static BindingFlags bFlags = BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static;
System.Object obj; // Object a field or property is animated on
string name; // Name of the field or property
System.Type objType; // Type object
FieldInfo fieldInfo; // FieldInfo object
PropertyInfo propertyInfo; // PropertyInfo object
public AniValue(System.Object o, string n)
{
obj = o;
name = n;
objType = obj.GetType();
fieldInfo = objType.GetField(n, AniValue.bFlags);
propertyInfo = objType.GetProperty(n, AniValue.bFlags);
if (fieldInfo == null && propertyInfo == null)
{
throw new System.MissingMethodException("Property or field '" + n
+ "' not found on " + obj);
}
}
// Get field or property
public System.Object Get()
{
if (propertyInfo != null)
{
/* The next line causes the Exception */
return propertyInfo.GetValue(obj, null);
}
else
{
return fieldInfo.GetValue(obj);
}
}
...
虽然我已限于使用C#,JIT,AOT,和反射,应的GetValue()触发JIT经验? UnityEngine.Color是一个结构,和Image类是作为x对象,这是UnityEngine.MonoBehaviour的子类的子类。颜色是图像的属性,而这正是该代码可以得到当异常发生时的值。
有趣的是,可以使用编译.NET 1.1的代码,并执行一切细。只有当你编译使用.NET 2.1没有异常发生。
我不知道是否有一个解决方案或解决这一点,但我会感兴趣的任何见解来的原因。
解决方案
IIRC,也有关于通过反射泛型警告。我的认为的调用输入和输出接口,而不是具体的类型,但也可以同样适用 - 中的特别是使用反射时的
就个人而言,与iPhone打交道时,我只是删除反思 - 这是更容易。我仍然在做元编程,但我预先生成常规代码(在完整的框架),然后我接手的MonoTouch。它似乎相当强劲的工作。