我知道我已经看到了几个有效的重复,但我目前没有找到它们,所以这里有一个快速的答案。
这与 API 中的对象参数、返回值和属性如何从 ObjC 导入到 Swift 有关。在 Xcode 6 beta 阶段的早期,所有对象参数/返回/属性都被导入为隐式展开的选项;例如
// in SKScene:
var view: UIView!
// in SKNode:
var children: [AnyObject]!
使用隐式解包可选 (IUO),您可以直接寻址 view(因此像 self.view.bounds 这样的代码是合法的)。它可能不存在,在这种情况下你会崩溃。并且某些操作在 IUO 类型上是不可能的,而在它包含的类型上是可能的。 IUO 的最佳实践是在处理它们的内容之前使用可选链接和可选绑定等结构检查它们是否为零。
ObjC-to-Swift 导入器必须对所有指向 ObjC 对象的属性/参数/返回执行此操作,因为在语法上任何指针都允许为 nil,即使在实践中它永远不会。 nil 的测试对于像 SKNode.children 这样从来不是 nil 的 API 来说有点麻烦(在无子情况下它是一个空数组)。
在过去的几个测试版和 Xcode 6 GM 中,Apple 审核了几个框架,以便将可能是 nil(如 UIViewController.view)的导入对象指针作为显式 Optionals 导入:
// SKScene
var view: UIView?
并且永远不会是 nil 的对象指针作为非可选类型导入:
// SKNode
var children: [AnyObject]
这意味着您可以安全地引用node.children,而无需担心崩溃,也无需检查nil。但是现在scene.view 是明确可选的,您必须在使用它之前检查它是否为零。
根据场景,您可以选择几种方法中的任何一种来测试或以其他方式处理可选:
- 强制解包:
self.view!.bounds.size
- 可选链接:
self.view?.bounds.size
- 可选绑定:
if let view = self.view { /* do something with */ view.bounds.size }
- 链接和绑定:
if let size = self.view?.bounds.size { /* do something with */ size }
阅读Swift 编程语言中的Optionals,详细了解每种语言的优缺点。