if-let 语句不解包可选
if-let statement doesn't unwrap optional
我 运行 在我的代码中发现了一些看起来很奇怪的东西,想知道是否有针对此行为的直接解释。给定以下语句:
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 语句应该为我解开条件语句——但这不是这里展示的行为。我无法访问 subcontrollerView
的 window
属性 除非我再次打开可选的。 x-code控制台returns如下:
Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>)
Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>)
<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>
解包的可选和 if-let 常量是一样的。为什么?
您的问题是AnyObject
。 (有疑问的时候,你的问题总是AnyObject
;是邪恶的类型,应该尽量避免。唯一更糟糕的是AnyObject?
。)
麻烦的是tabBarController.viewControllers
returns [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 的新 multi-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;
} } }
我 运行 在我的代码中发现了一些看起来很奇怪的东西,想知道是否有针对此行为的直接解释。给定以下语句:
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 语句应该为我解开条件语句——但这不是这里展示的行为。我无法访问 subcontrollerView
的 window
属性 除非我再次打开可选的。 x-code控制台returns如下:
Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>)
Optional(<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>)
<UILayoutContainerView: 0x7fbccd44e7f0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x7fbccacdde90>; layer = <CALayer: 0x7fbccd440e30>>
解包的可选和 if-let 常量是一样的。为什么?
您的问题是AnyObject
。 (有疑问的时候,你的问题总是AnyObject
;是邪恶的类型,应该尽量避免。唯一更糟糕的是AnyObject?
。)
麻烦的是tabBarController.viewControllers
returns [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 的新 multi-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;
} } }