对swift

时间:2016-08-11 18:54:56

标签: swift optional-values

我是swift的新手,我不太懂得如何正确使用可选值。

情况是:首先,我有一个模型类来存储其属性的一些值,并将请求发送到服务器以获取值。代码:

import Foundation

class User: NSObject {

    var name: String?

    func getInfo(updateUI: () -> ()) {
        let manager = AFHTTPSessionManager()
        manager.POST(URLString, parameters: nil, success: { (task: NSURLSessionDataTask, responseObject: AnyObject?) in

            let dic = responseObject as? NSDictionary
            self.name = dic?.objectForKey("name")
            updateUI()

        }, failure: { (task: NSURLSessionDataTask?, error: NSError) in
            log.obj(error)
    })

}

其次,我想在ViewController中使用此模型从服务器和更新UI获取值。代码:

class UserViewController: UIViewController {

    @IBOutlet var nameLabel: UILabel!
    var user = User()

    override func viewDidLoad() {
        super.viewDidLoad()

        user.getInfo({
            nameLabel.text = user.name!
        })
    }

}

我认为处理这项工作是一种危险的方式,因为当我想把它放在标签上时,没有任何东西可以确保我有一个特定的名字。它在大多数情况下都能很好地工作,但是如果无法从服务器获得正确的值,它就会崩溃(例如,密钥" name"没有值)。

我对上述问题有两点看法:

  1. 为以下属性提供默认值:var name = ""
  2. 在取消加样之前测试该值:

    if let foo = user.name {
        nameLabel.text = foo
    }
    
  3. 我想选择第一种方式,因为:

    1. 我认为在标签上显示默认字符串比崩溃更容易接受,因为无法取消扭曲可选值。
    2. 当我有更多值要使用时,代码会很长并且难以阅读。
    3. 我选择了正确的吗?或者他们两个都不了解可选值的用法,还有更好的方法吗?有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:3)

你可以放心地打开一个可选项或给它一个默认值,而不会像这样声明一个新变量:

nameLabel.text = user.name ?? ""

这称为nil coalescing运算符,将尝试解包一个可选项,如果unwrap不成功,则会为其提供您在运算符的rhs上放置的默认值。

答案 1 :(得分:3)

你的直觉是正确的,强行解包可选是不明智的。提供非零默认值会违背可选项的目的,这也是正确的。

if let foo = user.name绑定是这样做的一种合理方式,但是如果你所做的只是分配一个值,你可以通过使用nil合并运算符来节省大括号,如pbush25所述:

nameLabel.text = user.name ?? "Default Label Text"

这意味着“解包user.name,如果其值不是nil,请使用它。否则,请使用以下值:”例如,如果您想使用用户ID作为后备标签,您甚至可以将它们链接在一起文本,但ID可能也不存在:

nameLabel.text = user.name ?? user.id ?? "No name or ID"

即使您想要在可选值为nil的情况下崩溃,最好assert或使用preconditionFailure()而不是简单地强行打开可选项以便至少可以提供错误消息。