我会正确的:
有什么区别:
var test: String?
test = "this is an optional string"
if test != nil {
println("\(test!) IS NOT nil")
} else {
println("test is nil")
}
Run Code Online (Sandbox Code Playgroud)
和
if let test = test {
println("\(test) IS NOT nil")
} else {
println("test is nil")
}
Run Code Online (Sandbox Code Playgroud)
两者都在操场上输出相同的结果.
我知道隐式解包不被认为是安全的(在大多数情况下),但是,我在这里检查在打开之前值是否为零?
两种方法都是有效的,并且有不同的情况,其中一种被认为是更好的选择吗?
为什么我需要unwrapped在最终的return语句中解包变量?不是警卫应该处理这个吗?
func test() -> String {
let fmt = NSNumberFormatter()
let myValue:Double? = 9.50
guard let unwrapped = myValue else {
return ""
}
return fmt.stringFromNumber(unwrapped)
}
Run Code Online (Sandbox Code Playgroud)
错误:可选类型'String?'的值 没有打开; 你的意思是用'!' 要么 '?'?return fmt.stringFromNumber(unwrapped)
我正在尝试从 Firebase 读取并将标签设置为我得到的值
这是我的 ViewController 类顶部的样子:
import UIKit
import Firebase
class ProfileTabViewController: UIViewController {
//MARK: Properties
@IBOutlet weak var nameLabel: UILabel!
var userName = "userName"
Run Code Online (Sandbox Code Playgroud)
我有一个 Firebase 参考
var currentUserName = Firebase(url: "https://buzzmovieios.firebaseio.com/users/884962b7-9fd8-49db-b172-1ad7cb1414f4/Name")
Run Code Online (Sandbox Code Playgroud)
随机字符串是 Firebase 返回的 uid。
我试图在 viewDidAppear() 方法中获取用户名:
override func viewDidAppear(animated: Bool) {
print(currentUserName)
currentUserName.observeEventType(.Value) { (snap: FDataSnapshot!) in
let name = snap.value as! String
self.nameLabel.text = name
}
}
Run Code Online (Sandbox Code Playgroud)
let name 行工作正常。
print(name)
Run Code Online (Sandbox Code Playgroud)
这一行:
self.nameLabel.text = name
Run Code Online (Sandbox Code Playgroud)
原因:
致命错误:在展开可选值 (lldb) 时意外发现 nil
我试过了
let name = snap.value …Run Code Online (Sandbox Code Playgroud) func initializePickerViewProperties() {
let font = UIFont (name: "SanFranciscoDisplay-Regular", size: 30.0)
let highlightedFont = UIFont (name: "SanFranciscoDisplay-Bold", size: 35.0)
pickerView.font = font!
pickerView.highlightedFont = highlightedFont!
}
Run Code Online (Sandbox Code Playgroud)
相当简单,有问题的pickerView是一个AKPickerView
如果我删除强制解包,我会收到编译器错误。“可选类型 UIFont 的值未展开,您的意思是使用“!”还是“?”?
但是,当我强制打开它时,会出现运行时错误。“致命错误:在展开可选值时意外发现 nil”
我开始关注选项并强制解包,除了在一个特定的上下文中:当它是函数的返回类型时.
有什么区别:
func myFunction() -> NSData { ... }
func myFunction() -> NSData! { ... }
func myFunction() -> NSData? { ... }
Run Code Online (Sandbox Code Playgroud)
此外,当我使用返回值时NSData!,我被迫使用?看似奇怪的.
func myFunction() -> NSData! { ... }
let data = myFunction()
data?.write()
Run Code Online (Sandbox Code Playgroud)
为什么我需要?如果我强行打开回报?
我的观点是在某些地方我们知道变量根本不会有 nil 但由于某种原因我们不能在类的 init 函数中实例化它所以我们必须使它成为可选的。
我也知道我们可以使用可选的绑定或保护技术来轻松摆脱它。
但是在我看来,让应用程序因为隐式解包/强制解包而在一些非常愚蠢的错误中崩溃对于开发阶段的开发人员来说是有益的。
我的例子是:
class TopStoriesViewModelTests: XCTestCase {
var viewModel: TopStoriesViewModel!
override func setUp() {
super.setUp()
viewModel = TopStoriesViewModel(interactor: MockTopStoriesInteractor())
}
func testArticleDidVisited() {
viewModel.visited = xxxxxx
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我可以制作TopStoriesViewModel一个?then 保护它,或者在每个测试用例中都使用它,但我觉得没有必要。我知道我也可以使用viewModel?.xxx。但这不是重点。
我的问题是,在某些情况下,例如我给出的示例,强制解包/隐式解包是有益的,我是否正确。