U3D开发中关于脚本方面的限制-有关IOS反射和JIT的支持问题
U3D文档中说明了,反射在IOS是支持的,除了system.reflection.emit空间内的,其它都支持。JIT是不支持的。
本质上来说即是:只要不在运行时动态生成代码的行为都支持,reflection.emit下的功能可以动态的生成代码(生成程序集,生成类,生成函数,生成类型等,是真正的生成代码),JIT也能动态的生成代码(如C#生成的IL在各平台上运行时可以由JIT编译成汇编语言)。
其它的并不会生成代码的反射功能是可以用的,如 type.gettype, getfield, Activator.CreateInstance
文档如下:
Scripting restrictions
We strive to provide a common scripting API and experience across all platforms Unity supports. However, some platforms have inherent restrictions. To help you understand these restrictions and support cross-platform code, the following table describes which restrictions apply to each platform and scripting backend:
| Platform | Scripting Backend | Restrictions |
|---|---|---|
| Standalone | Mono | None |
| WebGL | IL2CPP | Ahead-of-time compile, No threads |
| iOS | IL2CPP | Ahead-of-time compile |
| Android | Mono | None |
| Android | IL2CPP | Ahead-of-time compile |
| Samsung TV | Mono | Ahead-of-time compile |
| Tizen | Mono | Ahead-of-time compile |
| XBox One | Mono | Ahead-of-time compile |
| XBox One | IL2CPP | Ahead-of-time compile |
| WiiU | Mono | Ahead-of-time compile |
| PS Vita | Mono | Ahead-of-time compile |
| PS Vita | IL2CPP | Ahead-of-time compile |
| PS4 | Mono | Ahead-of-time compile |
| PS4 | IL2CPP | Ahead-of-time compile |
| Windows Store | .NET | Uses .NET Core class libraries subset |
| Windows Store | IL2CPP | Ahead-of-time compile |
Ahead-of-time compile
Some platforms do not allow runtime code generation. Therefore, any managed code which depends upon just-in-time (JIT) compilation on the target device will fail. Instead, we need to compile all of the managed code ahead-of-time (AOT). Often, this distinction doesn’t matter, but in a few specific cases, AOT platforms require additional consideration.
System.Reflection.Emit
An AOT platform cannot implement any of the methods in the System.Reflection.Emit namespace. Note that the rest of System.Reflection is acceptable, as long as the compiler can infer that the code used via reflection needs to exist at runtime.
Serialization
AOT platforms may encounter issues with serialization and deserlization due to the use of reflection. If a type or method is only used via reflection as part of serialization or deserialization, the AOT compiler cannot detect that code needs to be generated for the type or method.
Generic virtual methods
Generic methods require the compiler to do some additional work to expand the code written by the developer to the code actually executed on the device. For example, we need different code for List with an int or a double. In the presence of virtual methods, where behavior is determined at runtime rather than compile time, the compiler can easily require runtime code generation in places where it is not entirely obvious from the source code.
Suppose we have the following code, which works exactly as expected on a JIT platform (it prints “Message value: Zero” to the console once):
using UnityEngine;
using System;
public class AOTProblemExample : MonoBehaviour, IReceiver {
public enum AnyEnum {
Zero,
One,
}
void Start() {
// Subtle trigger: The type of manager *must* be
// IManager, not Manager, to trigger the AOT problem.
IManager manager = new Manager();
manager.SendMessage(this, AnyEnum.Zero);
}
public void OnMessage<T>(T value) {
Debug.LogFormat("Message value: {0}", value);
}
}
public class Manager : IManager {
public void SendMessage<T>(IReceiver target, T value) {
target.OnMessage(value);
}
}
public interface IReceiver {
void OnMessage<T>(T value);
}
public interface IManager {
void SendMessage<T>(IReceiver target, T value);
}
When this code is executed on an AOT platform with the IL2CPP scripting backend, this exception occurs:
ExecutionEngineException: Attempting to call method 'AOTProblemExample::OnMessage<AOTProblemExample+AnyEnum>' for which no ahead of time (AOT) code was generated.
at Manager.SendMessage[T] (IReceiver target, .T value) [0x00000] in <filename unknown>:0
at AOTProblemExample.Start () [0x00000] in <filename unknown>:0
Likewise, the Mono scripting backend provides this similar exception:
ExecutionEngineException: Attempting to JIT compile method 'Manager:SendMessage<AOTProblemExample/AnyEnum> (IReceiver,AOTProblemExample/AnyEnum)' while running with --aot-only.
at AOTProblemExample.Start () [0x00000] in <filename unknown>:0
The AOT compiler does not realize that it should generate code for the generic method OnMessage with a T of AnyEnum, so it blissfully continues, skipping this method. When that method is called, and the runtime can’t find the proper code to execute, it gives up with this error message.
To work around an AOT issue like this, we can often force the compiler to generate the proper code for us. If we add a method like this to the AOTProblemExample class:
public void UsedOnlyForAOTCodeGeneration() {
// IL2CPP needs only this line.
OnMessage(AnyEnum.Zero);
// Mono also needs this line. Note that we are
// calling directly on the Manager, not the IManager interface.
new Manager().SendMessage(null, AnyEnum.Zero);
// Include an exception so we can be sure to know if this method is ever called.
throw new InvalidOperationException("This method is used for AOT code generation only. Do not call it at runtime.");
}
When the compiler encounters the explicit call to OnMessage with a T of AnyEnum, it generates the proper code for the runtime to execute. The method UsedOnlyForAOTCodeGeneration does not ever need to be called; it just needs to exist for the compiler to see it.
No threads
Some platforms do not support the use of threads, so any managed code that uses the System.Threading namespace will fail at runtime. Also, some parts of the .NET class libraries implicitly depend upon threads. An often-used example is the System.Timers.Timer class, which depends on support for threads.
U3D开发中关于脚本方面的限制-有关IOS反射和JIT的支持问题的更多相关文章
- FPGA开发中的脚本语言
多数FPGA开发者都习惯图形化界面(GUI).GUI方式简单易学,为小项目提供了一键式流程.然而,随着FPGA项目越来越复杂,在很多情况下GUI工具就阻碍了工作效率.因为GUI工具不能对整个开发过程提 ...
- u3d开发中可能会遇到的设计模式
最近一段时间,面试了一些程序员,当然主要招聘的岗位是Unity3D开发.面试过程中对于三年以上的程序员我都会问其在开发中是否会总结一些常用的设计模式和设计方法,当然目的只是想了解程序员的自我学习情况以 ...
- U3D开发性能优化笔记(待增加版本.x)
http://blog.csdn.net/kaitiren/article/details/45071997 此总结由自己经验及网上收集整理优化内容 包括: .代码方面: .函数使用方面: .ui注意 ...
- 解析iOS开发中的FirstResponder第一响应对象
1. UIResonder 对于C#里所有的控件(例如TextBox),都继承于Control类.而Control类的继承关系如下: 代码如下: System.Object System.Marsha ...
- CocoaPoda在iOS开发中的使用
CocoaPoda在iOS开发中的使用 CocoaPods 简介 CocoaPods是iOS开发中不可避免的依赖管理第三方的工具,能简化一些第三方库文件需要添加编译参数及依赖库的繁复工作 CocoaP ...
- gulp自己主动化任务脚本在HybridApp开发中的使用
眼下做前端开发的同学可能都熟悉grunt.fis之类的自己主动化构建工具.事实上在HybridApp开发中我们也能够使用这些工具来简化我们的工作.gulp就是一个比grunt,fis都先进的构建工具. ...
- 老李分享:Eclipse中开发性能测试loadrunner脚本
老李分享:Eclipse中开发性能测试loadrunner脚本 前篇我分享了如何用loadrunner搭建javauser的性能测试脚本环境,本次我来告诉大家如何在eclipse开发loadrunne ...
- VSCode调试Html中的脚本 vscode前端常用插件推荐,搭建JQuery、Vue等开发环境 vsCode 添加浏览器调试和js调试的方法总结 VS Code - Debugger for Chrome调试js
一.背景 使用Visual Studio Code写了一个简单的Html页面,想调试下其中script标签里的javascript代码,网上查了一通,基本都是复制粘贴或者大同小异的文章,就是要安装De ...
- React Native开发中自动打包脚本
React Native开发中自动打包脚本 在日常的RN开发中,我们避免不了需要将我们编写的代码编译成安装包,然后生成二维码,供需要测试的人员扫描下载.但是对于非原生的开发人员来说,可能不知如何使用X ...
随机推荐
- library之目录
组件之fragment: Android viewpager结合fragment的相关优化: 组件之webview: WebView的使用及实战(cookie同步和cookie清除); Android ...
- [UE4]虚幻引擎UE4如何制作可拖动(Drag and Drop)的背包(Scrollbox)(转载)
最终效果 由于隐私保护,不想截实际的效果图,下面给出了示意图,左边是背包A,右边是背包B,将其中的子项目从左侧拖往右侧的背包,然后在插入位置放置. 第一步: 制作一个user widget(在内容浏览 ...
- CRM 2016 升级CRM365之注意事项
https://docs.microsoft.com/zh-cn/previous-versions/dynamicscrm-2016/deployment-administrators-guide/ ...
- POJ3635 Full Tank?
[题解] 用dijkstra算法求最短路.同时考虑在每个节点加油(一单位)与否. [代码] #include <iostream> #include <map> #includ ...
- 第11章 拾遗5:IPv6和IPv4共存技术(3)_NAT-PT技术【全书完】
6.4 NAT-PT (1)NAT-PT和NAT的差别 ①NAT-PT(附带协议转换的网络地址转换)技术秉承NAT技术的思想,但在原理方面大有不同. ②NAT-PT和NAT本质的区别在于应用场合的不同 ...
- 第8章 传输层(1)_TCP/UDP协议的应用场景
1. 传输层的两个协议 1.1 TCP和UDP协议的应用场景 (1)TCP协议:如果要传输的内容比较多,需要将发送的内容分成多个数据包发送.这就要求在传输层用TCP协议,在发送方和接收方建立连接,实现 ...
- Java7 新特性: try-with-resources
Try-with-resources是java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源. 利用Try-Catch-Finally管理资源(旧的代码风格)在ja ...
- python中列表删除和多重循环退出
在学习python的时候,会有一些梗非常不适应,在此列举列表删除和多重循环退出的例子: 列表删除里面的坑 比如我们有一个列表里面有很多相同的值,假如:nums=[1,6,6,3,6,2,10,2,10 ...
- 【Selenium-WebDriver自学】Selenium-IDE不同的浏览器(八)
==================================================================================================== ...
- centos磁盘挂载|centos虚拟机硬盘不够怎么办?|centos虚拟机硬盘的扩展
Centos6磁盘挂载 添加一块磁盘 分区,格式化,挂载新磁盘 磁盘挂载 df -lh fdisk -l fdisk /dev/sdb 这个命令执行后依次输 n p 回车 回车 w fdisk -l ...