距离 Xcode 10.1 正式版发布已经将近一个月了,我们今天重新来回顾一下 Xcode 10.1 的新特性,以及已解决的问题和存在的问题。
本文主要参考了《Xcode 10.1 Release Notes》进行整理,同时你也可以查阅《Xcode 10 Release Notes》获取更多关于 Xcode 10 的细节。
接下来我们将以新特性(New Features)、已解决的问题(Resolved Issues)、已知问题(Known Issues)等几方面来介绍 Xcode 10.1 在各模块上的更新。
1. General / 通用
新特性
- 支持 arm64e 处理器架构(预览版)
如果你想尝试尚处于开发者预览版的 arm64e,请在 Xcode 项目编辑器中选择你的 iOS app 对应的 target,在 Build Settings 中找到 “Architectures” 设置项,选择 “Other…” 选项,然后添加手动添加 arm64e 到 architectures 列表中。
注:目前 App Store 和 TestFlight 并不接受包含 arm64e 的提交,所以当我们 Archive 后在 Organizer 窗口要向苹果提交发布时,Xcode 会自动移除掉 app 包中 arm64e 的内容。
已解决的问题
菜单中 Navigate > Open in… 的导航栏 UI 不再将窗口中的各个 tabs 显示为单独的窗口,每个窗口都有一个 tab。
xed 工具现在使用由当前
xcode-select
或DEVELOPER_DIR
环境变量指定的 Xcode。
2. Apple Clang Compiler / 苹果 Clang 编译器
已解决的问题
- 对 iOS 12.1 beta 2 中的
libunwind
库进行修改,解决了在 iPhone XS 和 iPhone XS Max 上运行少部分 app 的问题。
3. Asset Catalog / 资源目录
已知问题
- 项目中如果包含了 asset catalogs 并使用 Xcode 10.0 或者更高版本的构建的 app,且其 Deployment Target(指最低支持的系统版本)设为 iOS 9.0、9.1 或者 9.2 时,会生成与这些 iOS 版本的运行时不兼容的内容(具体表现为:在系统版本为 9.0 ~ 9.2.1 之间的真机设备上通过 App Store 或者 TestFlight 下载安装该 app 并运行,会出现偶现的 Crash)。
注:关于这个问题,相信大家已经很熟悉了,网上有很多讨论,我们之前也发了几条相关的小集。它是在 Xcode 10.0 上开始出现的,而在 Xcode 10.1 刚发布时,苹果声称已经解决了,后面大家纷纷表示这个问题仍然存在。不过根据微博上的最新消息和小伙伴们的亲自验证,苹果已经在服务端解决了这个问题,开发者通过 Xcode 10.1 打的 ipa 包在上传到 App Store Connect 后台,苹果在处理包的过程中会自动修复。
已解决的问题
- 增加 40mm 和 44mm 的孔(wells)用于解决指定正确的图标大小的难题。
4. Build System / 构建系统
已解决的问题
新的构建系统支持“按需资源”(On Demand Resources,ODR)。
修复了问题:在为 .xib 文件或 storyboards 使用基本本地化时,不会将与基本文件关联的各个本地化的 .xib 文件或 storyboards 编译到产品中。
5. Debugging / 调试
新特性
- 对于异常断点(Exception Breakpoints)的断点编辑器增加了一个 “ignore count” 字段。
6. Devices / 设备
已解决的问题
- 运行 iOS 12 或更高版本的设备从 “Devices” 窗口中请求获取屏幕截图的问题。
7. Interface Builder / 界面构建工具
新特性
- 现在,在画布中拖动控件(Control-dragging)以添加约束总是包括所有四个方向,而不仅仅是最接近拖动方向的方向。
已解决的问题
修复了问题:在将视图与
UIScrollView
的子视图添加约束时, Auto Layout 会错误报告问题。提高了画布(canvas)的性能:当底部设备栏在 iPhone XS、iPhone XS Max 和 iPhone XR 之间切换时。
修复了导致预览助手编辑器(Preview assistant editor)中监视内容布局与设备栏选择不匹配的问题。
现在,当启用
@IBDesignable
视图时,将使用新的构建系统进行编译。
8. Simulator / 模拟器
已知问题
- 如果有另一个进程,例如
simctl
,在模拟器正在打开时关闭了模拟的设备,则模拟器在下次启动设备时无法正确地重新连接到模拟器。如果你安装了多个版本的 Xcode,则在其他版本的 Xcode 中运行模拟器是可能也会遇到这个问题。
临时解决方案:退出并重新启动模拟器。要在不关闭所有模拟器的情况下退出,请先按住 Option 键并选择 Simulator > Quit Simulator…,然后在出现的对话框中选择 “Keep Running”。
9. Swift Compiler / Swift 编译器
已知问题
- 如果你在一个类的实例对象上通过使用 protocol 或 extension 中定义的 nonmutating setter 来间接修改属性,则 Swift 编译器可能会出现错误编译:在调用该属性的 getter 方法之后就直接释放该实例对象。这可能会导致程序崩溃或在运行时出现不可预测的行为。
例如:
1 | protocol SomeProtocol { } |
临时解决方案:将该操作分解为多个语句,以便 get 和 set 操作在不同的语句中发生:
1 | let someObject = SomeClass() |
已解决的问题
Xcode 中的 Playgrounds 不再记录关于在运行时类型无法解码的字段的信息。
现在编译 Swift 代码时会始终报告导致任何失败的错误。例如,之前可能会发生诸如 “Command CompileSwiftSources failed with a zeroo exit code” 之类的消息,而没有伴随的失败原因。
包含空格的长文件路径将不会再导致构建失败。
NSBundle
类的bundleForClass:
初始化方法现在与 Swift 类保持一致,包括即使不在最新的操作系统版本上运行。现在可以将以函数类型作为参数的泛型类的 “let property” 成功传递给另一个函数或方法。
1 | class A<B> { |
对嵌套上下文中(nested context)的捕获值所做的更改现在将反映在外部上下文中(outer context)。
现在可以成功调用一个在协议类型(protocol type)的值上返回 Self 的变异方法(mutating method):
1 | protocol Example { |
- 编译器现在可以成功地将一个异构类对象(heterogeneous class objects)数组生成为 AnyObject 数组:
1 | func f(_: [AnyObject]) |
10. Swift Standard Library / Swift 标准库
已解决的问题
FixedWidthInteger
协议中的unsafeAdding(_:)
,unsafeSubtracting(_:)
,unsafeDivided(by:)
, 以及unsafeMultiplied(by:)
等方法已弃用(deprecated),并将在以后的版本中删除。
这些方法在溢出条件下会产生未定义的行为。因此在算术运算的情况下,可以使用 assert
和 addingReportingOverflow(_:)
方法或者 &+
运算符的组合,这两者都会在溢出的情况下有明确定义的结果。
11. Source Control / 代码控制管理
已解决的问题
- 当从 GitLab.com 或者 GitLab 自托管账户进行克隆(cloning)仓库时,组织仓库(organizational repositories)目前可以与个人仓库(personal repositories)一起显示了。
12. Testing / 测试
已知问题
- 当开启并行化测试(test parallelization)时,性能分析测试(profiling tests)的结果不能正确地表现。
临时解决方案:当进行分析测试时可以通过如下方式禁用并行测试:在 Xcode 菜单栏中打开 Product > Scheme > Edit Scheme… > Test > Info,选择测试 target 旁边的 “Options” 按钮,然后禁用 “Execute in parallet” 复选框。
已解决的问题
使用旧版构建系统(legacy build system)的项目中的 UI 测试,目前可支持在 iPhone XS 和 iPhone XS Max 上运行了。
如果一个 UI 测试的目标 app 在模拟器上进行测试期间崩溃了,则现在可以将其正确地报告为测试失败,而不是像之前那样被错误地视为成功测试,或者显示有关 “Application state unknown” 失败信息。
Xcode 10.1 beta 2 及更高版本支持在运行 iOS 12 beta 版的设备上进行 UI 测试。
修复了如果在测试已经开始后的任何时刻添加观察者,则此时添加到
XCTestObservationCenter
共享实例对象上的观察者的testBundleDidFinish:
方法不会被调用的问题(例如:在所有当前注册的观察者上调用了testBundleWillStart:
方法之后)。当接收器(receiver)是一个菜单项或者菜单项的子视图时,
XCUIElement
类的click
和hover
方法现在可以自动滚动菜单了。
参考连接
注:本文翻译内容如有描述不准确的地方,请参考上述英文原文。