我是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"没有值)。
我对上述问题有两点看法:
var name = ""
在取消加样之前测试该值:
if let foo = user.name {
nameLabel.text = foo
}
我想选择第一种方式,因为:
我选择了正确的吗?或者他们两个都不了解可选值的用法,还有更好的方法吗?有人可以帮帮我吗?
答案 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()
而不是简单地强行打开可选项以便至少可以提供错误消息。