Ios 如果let语句没有';t展开可选

Ios 如果let语句没有';t展开可选,ios,swift,optional,Ios,Swift,Optional,我在代码中遇到了一些奇怪的东西,我想知道是否有一个简单的解释可以解释这种行为。鉴于以下声明: if let tabBarController = topViewController as? UITabBarController { for subcontroller in tabBarController.viewControllers! { println(subcontroller.view) if let subcon

我在代码中遇到了一些奇怪的东西,我想知道是否有一个简单的解释可以解释这种行为。鉴于以下声明:

    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语句应该为我打开条件,但这不是这里展示的行为。我无法访问
subcrollerview
窗口
属性,除非我再次打开可选文件。x代码控制台返回以下信息:

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>>  
Optional()
可选()

未包装的可选值和if let常量相同。为什么?

您的问题是
任何对象
。(当有疑问时,你的问题总是
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新的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;
            } } }

如果您的可选项为nil,则不会展开任何内容。对,但请看控制台输出——它不是nil,对我来说,它看起来像一个bug,您能将其隔离在一个小项目中吗?如果是这样的话,你可以把它贴在这里,我们可以自己看看。如果仍然存在问题,该项目将非常适合向苹果公司提交雷达。您可以对您的项目进行清理(完全清理,即选项清理)并重新编译吗?只是清理了项目并重新编译——问题没有得到解决。我会整理一个小项目,然后马上发布。这是一个非常好的答案@Rob-为什么苹果使用AnyObject作为abBarController.viewControllers的返回类型。为什么不返回一个[UIViewController]数组呢?我想是因为ViewController都是UIViewController的子类?。。。但这似乎是一个丑陋的解决方案,因为我们仍在向Swift接口过渡。ObjC接口返回一个
NSArray
,它不提供类型信息。苹果显然正在使用的自动转换脚本在Swift中被翻译成
[AnyObject]?
。为了让它变得与众不同,苹果开发者不得不手工修改API。他们在每个版本中都是一步一步的做,但是还有很多部分还没有修复。事实上。。。我猜没有真正的解决方案,因为在tabBarController中ViewController子类类型都可能不同。是的,非常感谢您消除了这一困惑,rob。如果有人对源代码感兴趣,可以在这里发布:。等等!是可选对象吗?