Unity3d用户手册 AdvancediOS 设备故障排除

来源:互联网 发布:淘宝网男士羽绒服 编辑:程序博客网 时间:2024/05/22 02:02
iOS 设备故障排除
对于 iOS 来说,在某些情况下,游戏可以在 Unity 编辑器中完美运行,但在实际设备上却无法运行甚至不能启动。这些问题通常是由代码或内容质量引起的。本部分将介绍最常见的几种情况。

游戏停止响应一段时间后,Xcode 状态栏显示"中断 (interrupt)"。
导致这一现象有多种原因,主要原因包括:

脚本错误,如使用未初始化的变量等。
使用第三方 Thumb 编译本地库。这种库在 iOS SDK 连接器中触发已知问题并可能产生随机崩溃。
使用具有值类型的泛型类型作为参数(例如, List<int>、List<SomeStruct>、List<SomeEnum> 等)用于序列化的脚本属性。
在启用当托管代码剥离 (managed code stripping) 时,使用反射。
本机插件接口出错(托管代码的方法签名不匹配本机代码的函数签名)。
XCode 调试控制台的信息有助于检测此类故障(Xcode 菜单:查看 (View) > 调试区 (Debug Area) > 激活控制台 (Activate Console))。

Xcode 控制台显示 "Program received signal: “SIGBUS” 或 EXC_BAD_ACCESS 错误
此消息通常在应用程序收到 NullReferenceException 时出现在 iOS 设备。有两种方式找出发生错误的位置:

托管堆栈跟踪:
从 3.4 版开始 Unity 包含基于软件的空引用 (NullReferenceException) 处理。AOT 编译器包含每次访问对象的一种方法或变量时,快速查看所有空引用。这一功能影响了脚本的性能,这也是为什么只在开发构建中启用该功能的原因(在基础版许可证书中,用户可以在构建设置 (Build Setting) 对话框中打开“开发构建 (development build)” 选项,但 iOS 专业版许可证书用户需要另外启用“脚本调试 (script debugging)” 选项)。 如果上述内容都正确,而错误实际出现在 .NET 代码中,那么您将不会再看到 EXC_BAD_ACCESS, 相反,.NET 异常文本将要 Xcode 控制台中显示(或者代码在 "catch" 语句处理)。典型的输出可能是:

Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required.
  at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
这表明错误发生在 DayController 类的 handleTimeOfDay 方法中,是一个协同程序。 此外,如果它是脚本代码,就会提示出错误所在的行号(例如:"DayController.js:122 ")。问题语句可能如下:

 Instantiate(_imgwww.assetBundle.mainAsset);
如果脚本在没有首先检查下载是否正确的前提下访问资源包,可能发生这种错误。

本机堆栈跟踪:
本机堆栈跟踪对于故障调查是一项更为强大的工具,但是,使用它需要一些专业技术。通常在发生此类本机(硬件内存访问)故障之后通常不能继续。要进行本机堆栈跟踪需要在 Xcode 调试控制台输入 bt all。仔细检查显示的堆栈跟踪,它们可能包括了错误来源信息。您可能会看到这样的信息:

...
Thread 1 (thread 11523):
#0 0x006267d0 in m_OptionsMenu_Start ()
#1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr ()
#2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at /Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487
#3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked ()
...
首先应该找到 "Thread 1" 的堆栈跟踪,这是主线程。堆栈跟踪的第一行将指向发生错误的位置。在这个示例中,跟踪显示 NullReferenceException 发生在 "OptionsMenu" 脚本中的 "Start" 方法。仔细查看这一方法实现便可发现故障的原因。很明显,NullReferenceExceptions 发生在 Start 方法,对初始化顺序做出了错误的假设。 在某些情况下,调试控制台中只可以看到一小部分堆栈跟踪:

Thread 1 (thread 11523):
#0 0x0062564c in start ()
这表明在应用程序发布期间,已经去除本地符号。通过以下步骤可获得完整的堆栈跟踪信息:

在设备上删除应用程序。
清除所有目标。
构建并运行。
再次获得如上所述的堆栈跟踪信息。
将外部库链接到 Unity iOS 应用程序时,EXC_BAD_ACCESS 开始发生。
这通常在外部库由ARM Thumb 指令集编译时发生。目前这种库不兼容 Unity。不用 Thumb 指令重新编译库,即可轻松解决这一问题。库的 Xcode 工程重新编译可使用以下步骤:

在 Xcode, 从菜单中选择 "查看 (View)" > "导航器 (Navigators)" > "显示工程导航器 (Show Project Navigator)"
选择 "Unity-iPhone" 工程,激活"构建设置 (Build Settings)" 选项卡
在搜索字段输入:"Other C Flags"
在此处添加 -mno-thumb 标志并重新构建库。
如果该库的源不可用,应联络提供商,取得库的 non-thumb 版本。

Xcode 控制台显示 "WARNING -> applicationDidReceiveMemoryWarning()",应用程序随即崩溃
(有时会看到 Program received signal: 之类的信息。) 该警告信息通常不会使程序彻底崩溃,它仅仅提示 IOS 设备内存不足,要求释放更多的内存空间。通常,邮件 (Mail) 等后台进程可以释放一些内存空间,从而使应用程序继续运行。但是,如果应用程序继续使用内存或要求更多,操作系统最终将杀掉应用程序,其中可能包括您的程序。Apple 不会提示最低要求多大的内存空间。但是经验显示如果有不少于 50% MB 的 RAM 空间(如第 2 代 ipad ~200-256 MB 的内存),运行程序时就不会出现重大的内存使用问题。 最主要的衡量标准是应用程序会占用多大的 RAM 空间。应用程序占用的 RAM 空间主要由四大部分组成:

应用程序代码( OS 需要加载并将应用程序代码保存在 RAM 中,但在必要时会丢弃部分代码)
本地内存(引擎使用本地内存将其状态、资源等保存到 RAM)
托管内存(用于 Mono 运行时间,保存 C# 或 JavaScript 对象)
GLES 驱动程序内存池:纹理、帧缓存、编译着色器等。
应用程序内存使用可通过三种 Xcode 工具进行追踪:活动监视器 (Activity Monitor)、对象分配器 (Object Allocations) 和 VM 追踪器 (VM Tracker)。您可以从 Xcode 运行菜单: 作品 (Product) > 配置 (Profile) 中启动,然后选择特定工具。活动监视器 (Activity Monitor) 工具显示包括实际内存在内的所有过程统计信息,这可以看作是应用程序使用的 RAM 总量。请注意: OS 和 设备的 HW 版本组合可能明显影响内存使用数量,因此,在对比不同设备获得的数量时,应谨慎对待。


注意:内部分析器只显示 .NET 脚本分配的内存。内存使用总量可通过 Xcode 工具确定,如上图所示。该数字包括一部分应用程序的二进制,一些标准的框架缓冲区、Unity 引擎的内部状态缓冲区、.NET 运行时间内存(数值由内部分析器显示)、GLES 驱动程序内存和其他杂项。


本教程文章由游戏蛮牛unity3d教程整理推荐


0 0
原创粉丝点击