我在我的代码中遇到了一些似乎很奇怪的事情,并且想知道这种行为是否有直接的解释。鉴于以下声明:
if let tabBarController = topViewController as? UITabBarController {
for subcontroller in tabBarController.viewControllers! {
println(subcontroller.view)
if let subcontrollerView = subcontroller.view {
println(subcontrollerView)
println(subcontrollerView!)
if subcontrollerView!.window != nil && subcontroller.isViewLoaded() {
topViewController = subcontroller as? UIViewController
break;
}
}
}
}
据我所知,if-let语句应该为我打开条件 - 但这不是这里展示的行为。除非我再次打开可选项,否则无法访问window
的{{1}}属性。 x-code控制台返回以下内容:
subcontrollerView
unwrapped optional和if-let常量相同。为什么呢?
答案 0 :(得分:6)
您的问题是AnyObject
。 (如果有疑问,你的问题总是AnyObject
;这是一种应该尽可能避免的邪恶类型。唯一更糟的是AnyObject?
。)
问题是tabBarController.viewControllers
返回[AnyObject]?
,而可选的促销可能会导致事情横向发展。它可能会将AnyObject?
推广到AnyObject??
,然后会感到困惑。这有点像编译器错误,但也只是AnyObject
带来的疯狂。所以答案就是尽可能快地摆脱它。
而不是:
for subcontroller in tabBarController.viewControllers! {
你想要这个:
if let viewControllers = tabBarController.viewControllers as? [UIViewController] {
for subcontroller in viewControllers {
所以完整的代码是这样的:
if let tabBarController = topViewController as? UITabBarController {
if let viewControllers = tabBarController.viewControllers as? [UIViewController] {
for subcontroller in viewControllers {
if let subcontrollerView = subcontroller.view {
if subcontrollerView.window != nil && subcontroller.isViewLoaded() {
topViewController = subcontroller
break;
} } } } }
但我们可以做得更好。首先,可选链接通常是管理多个if-let的更好方法,当它不能正常工作时,我们可以使用Swift 1.2的新的if-if-let语法来实现:
if let tabBarController = topViewController as? UITabBarController,
viewControllers = tabBarController.viewControllers as? [UIViewController] {
for subcontroller in viewControllers {
if subcontroller.view?.window != nil && subcontroller.isViewLoaded() {
topViewController = subcontroller
break;
} } }