可选类型 'String?' 的值必须解包为类型'String'数组的值?

  • 本文关键字:String 类型 数组 ios swift
  • 更新时间 :
  • 英文 :


Swift的新手,我正在尝试理解这里的打字

我有下面的代码

@IBAction func randomImage(_ sender: Any) {
let path = Bundle.main.path(forResource: "imageList", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path!)

let data = dict!.object(forKey: "Images") as! [String]

imageView.image = UIImage(named: data.randomElement())

}

如上所示,首先我有dict!以确保dict可用,然后data将被类型化为字符串数组[String]

现在我不明白的部分是为什么data.randomElement()给我错误

可选类型"String?"的值必须展开为"String"类型的值

使用"?"进行聚合当可选值包含"nil"时提供默认值

使用"!"强制展开如果可选值包含"nil",则中止执行

根据建议,我可以逃脱data.randomElement()!的惩罚,但为什么需要这样做?

randomElement()函数返回一个Optional,因为从中提取的集合可能为空。如果是,函数将返回nil。

摆脱使用!强制展开运算符(以及隐式展开选项等变体(的习惯我将!称为";如果为零则崩溃";操作人员这就是它的作用。

您应该使用if let语法(可选绑定(重写代码

@IBAction func randomImage(_ sender: Any) {
if let path = Bundle.main.path(forResource: "imageList", ofType: "plist"),
let dict = NSDictionary(contentsOfFile: path),
let data = dict.object(forKey: "Images") as? [String],
let image = UIImage(named: data.randomElement()) {
imageView.image = image
} else {
// Unable to load image
}
}

对于类似的化合物if let,如果结果为零,则表达式在每一步都会退出。如果结果有效,它将继续执行If语句,并且新的临时变量现在是非可选的。

一旦您完成了复合if let中的最后一个let,您就可以在image中安装一个UIImage到您的图像视图中。

如果任何步骤失败,则运行else子句。你可以在那里做任何你想做的事情——安装一个默认的映像,在imageView中安装nil来删除它,打印到控制台,等等。(尽管如果要在图像视图中安装nil图像,可以稍微简化代码。(


编辑:

除了if let可选绑定之外,您还可以使用guard语句。

CCD_ 14任选结合表示";试着打开这个可选选项。如果成功,请创建一个仅在If语句体内部定义的变量,并执行If语句。

相反,guard说";试着打开这个可选选项。如果成功,请继续。如果失败,请执行退出当前作用域的代码块。

当你需要检查一系列的事情,并想在一切都好的时候继续做下去,但如果出现问题,就退出。

if let选择性结合可导致压痕水平不断增加:

func foo() {
if let a = anOpitonal {
// Do stuff
if let b = a.someOtherOptional {
// Do more stuff
if let c = b.yetAnotherOptional {
// Still more code that only runs if all 3 unwraps work
}
}
}
}

相比之下,你可以用这样的卫士来写:

func foo() {
guard let a = anOpitonal else { return }
// Do stuff
guard let b = a.someOtherOptional else { return }
// Do more stuff
guard let c = b.yetAnotherOptional  else { return }
// Still more code that only runs if all 3 guard statements work
}

相关内容

最新更新