在Swift中使用可选值时,IF语句错误地评估为True

时间:2016-02-13 21:50:42

标签: ios swift cocoa

我已经设置了我的视图控制器,以便在.centered-block { display: inline-block; position: relative; width: 100px; /* you would like to have a fixed width */ } .centered-block > h3 { position: absolute; width: 100%; top: 50%; transform: translateY(-50%); } 方法即将返回时发送通知。例如:

-viewDidLoad

我的class MyViewController: UIViewController{ override func viewDidLoad() { super.viewDidLoad() //Do Stuff var notificationCenter = NSNotificationCenter.defaultCenter(); notificationCenter.postNotificationName("AViewControllerDidLoadNotification", object: self); } } 班正在收听此通知并实施此图片中显示的方法。enter image description here

如果图片没有加载,该方法会将视图控制器发送的通知视为唯一的参数,然后测试AppDelegate的{​​{1} property具有非nil值。如果title属性为非nil,则记录标题。

但是,正如您在调试器面板中看到的那样,视图控制器的UIViewController属性为title,而title语句仍在评估nil。< / p>

我无可否认是可选值的新手。但是我在一个快速的游乐场重新创建了这种情况,if语句的评估结果为false。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

由于notification.object?.title本身不是一个UIViewController,因此你使用表达式notification.object非常奇怪,你已经陷入了奇怪的境地。它是一个AnyObject。

现在,AnyObject没有已知的属性,所以它没有title,你的表达式似乎甚至不应该编译。但是,通过来自Objective-C的某些奇怪的特殊分配,事实上你被允许询问AnyObject的属性。但是当你这样做时,结果本身就是一个Optional,因为不存在这样的属性。

因此,您实际上是在测试,而不是视图控制器的title属性的值,但是这个未知对象是否首先具有 title属性;如果实际上 具有title属性,那么title属性的值是双重包装在Optional中。< / p>

要清楚地看到这一点,只需测试这个(愚蠢的)代码:

let n = NSNotification(name: "Howdy", object: "Hi")
let t = n.object?.title

查看 t是什么类型。它不是String?;它是String??。这是你的双包裹可选。这意味着它成为一个Optional-wrapping-a-String,以防该对象被证明具有title属性,但为了以防万一,该值本身已包含在可选的。

因此,您的测试不会按照您的意愿执行。要做你想做的事,只要说得更清楚。您需要先将object强制转换为UIViewController ,然后然后检查其title。像这样:

func aViewControllerDidLoad(notification:NSNotification) {
    if let vc = notification.object as? UIViewController {
        if vc.title != nil {
            // ...
        }
    }
}