来自字符串插值的警告
Warnings from String interpolation
我遇到了自己无法解决的问题。我尝试过上网,但没有成功。
我对 Swift 和编码还是很陌生,现在正在按照帮助我创建应用程序的指南进行操作。
不幸的是,据我所知,该应用程序是为 Swift 3 编写的,由于我使用的是 Swift 4.
,因此给我带来了一些问题
我必须要给出此警告的行:
String interpolation produces a debug description for an optional value; did you mean to make this explicit?
Use 'String(describing:)' to silence this warning Fix
Provide a default value to avoid this warning Fix
但是,当我单击 Xcode 的解决方案之一时,我遇到了另一个问题。
如果我使用第一个修复程序,应用程序崩溃并且我收到以下消息:
Thread 1: Fatal error: Unexpected Segue Identifier;
如果我使用第二个修复程序,我必须指定一个默认值。而且我不知道这应该是什么。
整段代码如下。
这是导致问题的以 guard let selectedMealCell
开头的行和 default:
之后的最后一行。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "") {
case "AddItem":
os_log("Adding a new meal.", log: OSLog.default, type: .debug)
case "ShowDetail":
guard let mealDetailViewController = segue.destination as? MealViewController else {
fatalError("Unexpected destination: \(segue.destination)")
}
guard let selectedMealCell = sender as? MealTableViewCell else {
fatalError("Unexpected sender: \(sender)")
}
guard let indexPath = tableView.indexPath(for: selectedMealCell) else {
fatalError("The selected cell is not being displayed by the table")
}
let selectedMeal = meals[indexPath.row]
mealDetailViewController.meal = selectedMeal
default:
fatalError("Unexpected Segue Identifier; \(segue.identifier)")
}
}
因此,第一个建议的修复对您有用。它消除了编译时警告,尽管不可否认 String(describing:)
是一个薄弱的解决方案。
在这两种情况下,您都需要解包可选值。对于第一种情况,您应该使用:
guard let selectedMealCell = sender as? MealTableViewCell else {
if let sender = sender {
fatalError("Unexpected sender: \(sender))")
} else {
fatalError("sender is nil")
}
}
在第二种情况下:
fatalError("Unexpected Segue Identifier; \(segue.identifier ?? "")")
然后你得到一个运行时错误:
"Unexpected Segue Identifier;"
这表明您的 switch
与前 2 个案例不匹配,运行 与 default
案例不匹配。崩溃是因为您的代码显式调用了 fatalError
。您的 segue.identifier
显然是一个空字符串。
所以你的问题实际上是在你的情节提要中。您需要为您的 segues 分配标识符。单击视图控制器之间的转场箭头,并将标识符 "AddItem"
和 "ShowDetail"
分配给正确的转场。 segue identifier在Xcode.
右侧的Attributes Inspector中赋值
如果您准备为 Optional 编写一个小扩展,它可以使插入可选变量值的业务变得不那么痛苦,并且避免必须重复编写 optionalVar ?? ""
:
鉴于:
extension Optional: CustomStringConvertible {
public var description: String {
switch self {
case .some(let wrappedValue):
return "\(wrappedValue)"
default:
return "<nil>"
}
}
}
那你可以这样写:
var optionalWithValue: String? = "Maybe"
var optionalWithoutValue: String?
print("optionalWithValue is \(optionalWithValue.description)")
print("optionalWithoutValue is \(optionalWithoutValue.description)")
给出:
optionalWithValue is Maybe
optionalWithoutValue is <nil>
你也可以写 print("value is \(anOptionalVariable)")
——.description
是多余的,因为 print() 无论如何都使用 CustomStringConvertible.description——但尽管它有效,你仍然会收到烦人的编译器警告。
您可以使用以下内容为 nil 值自动生成“nil”(或任何其他字符串),对于 non-nil 值使用 CustomStringConvertible
[=16 提供的 description
=]
extension String.StringInterpolation {
mutating func appendInterpolation<T: CustomStringConvertible>(_ value: T?) {
appendInterpolation(value ?? "nil" as CustomStringConvertible)
}
}
对于您自己的类型,您必须符合 CustomStringConvertible
才能工作:
class MyClass: CustomStringConvertible {
var description: String {
return "Whatever you want to print when you use MyClass in a string"
}
}
通过此设置,您可以像使用任何其他类型一样简单地使用可选类型,而不会出现任何编译器警告。
var myClass: MyClass?
myClass = MyClass()
print("myClass is \(myClass)")
我遇到了自己无法解决的问题。我尝试过上网,但没有成功。
我对 Swift 和编码还是很陌生,现在正在按照帮助我创建应用程序的指南进行操作。
不幸的是,据我所知,该应用程序是为 Swift 3 编写的,由于我使用的是 Swift 4.
,因此给我带来了一些问题我必须要给出此警告的行:
String interpolation produces a debug description for an optional value; did you mean to make this explicit?
Use 'String(describing:)' to silence this warning Fix
Provide a default value to avoid this warning Fix
但是,当我单击 Xcode 的解决方案之一时,我遇到了另一个问题。
如果我使用第一个修复程序,应用程序崩溃并且我收到以下消息:
Thread 1: Fatal error: Unexpected Segue Identifier;
如果我使用第二个修复程序,我必须指定一个默认值。而且我不知道这应该是什么。
整段代码如下。
这是导致问题的以 guard let selectedMealCell
开头的行和 default:
之后的最后一行。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch(segue.identifier ?? "") {
case "AddItem":
os_log("Adding a new meal.", log: OSLog.default, type: .debug)
case "ShowDetail":
guard let mealDetailViewController = segue.destination as? MealViewController else {
fatalError("Unexpected destination: \(segue.destination)")
}
guard let selectedMealCell = sender as? MealTableViewCell else {
fatalError("Unexpected sender: \(sender)")
}
guard let indexPath = tableView.indexPath(for: selectedMealCell) else {
fatalError("The selected cell is not being displayed by the table")
}
let selectedMeal = meals[indexPath.row]
mealDetailViewController.meal = selectedMeal
default:
fatalError("Unexpected Segue Identifier; \(segue.identifier)")
}
}
因此,第一个建议的修复对您有用。它消除了编译时警告,尽管不可否认 String(describing:)
是一个薄弱的解决方案。
在这两种情况下,您都需要解包可选值。对于第一种情况,您应该使用:
guard let selectedMealCell = sender as? MealTableViewCell else {
if let sender = sender {
fatalError("Unexpected sender: \(sender))")
} else {
fatalError("sender is nil")
}
}
在第二种情况下:
fatalError("Unexpected Segue Identifier; \(segue.identifier ?? "")")
然后你得到一个运行时错误:
"Unexpected Segue Identifier;"
这表明您的 switch
与前 2 个案例不匹配,运行 与 default
案例不匹配。崩溃是因为您的代码显式调用了 fatalError
。您的 segue.identifier
显然是一个空字符串。
所以你的问题实际上是在你的情节提要中。您需要为您的 segues 分配标识符。单击视图控制器之间的转场箭头,并将标识符 "AddItem"
和 "ShowDetail"
分配给正确的转场。 segue identifier在Xcode.
如果您准备为 Optional 编写一个小扩展,它可以使插入可选变量值的业务变得不那么痛苦,并且避免必须重复编写 optionalVar ?? ""
:
鉴于:
extension Optional: CustomStringConvertible {
public var description: String {
switch self {
case .some(let wrappedValue):
return "\(wrappedValue)"
default:
return "<nil>"
}
}
}
那你可以这样写:
var optionalWithValue: String? = "Maybe"
var optionalWithoutValue: String?
print("optionalWithValue is \(optionalWithValue.description)")
print("optionalWithoutValue is \(optionalWithoutValue.description)")
给出:
optionalWithValue is Maybe
optionalWithoutValue is <nil>
你也可以写 print("value is \(anOptionalVariable)")
——.description
是多余的,因为 print() 无论如何都使用 CustomStringConvertible.description——但尽管它有效,你仍然会收到烦人的编译器警告。
您可以使用以下内容为 nil 值自动生成“nil”(或任何其他字符串),对于 non-nil 值使用 CustomStringConvertible
[=16 提供的 description
=]
extension String.StringInterpolation {
mutating func appendInterpolation<T: CustomStringConvertible>(_ value: T?) {
appendInterpolation(value ?? "nil" as CustomStringConvertible)
}
}
对于您自己的类型,您必须符合 CustomStringConvertible
才能工作:
class MyClass: CustomStringConvertible {
var description: String {
return "Whatever you want to print when you use MyClass in a string"
}
}
通过此设置,您可以像使用任何其他类型一样简单地使用可选类型,而不会出现任何编译器警告。
var myClass: MyClass?
myClass = MyClass()
print("myClass is \(myClass)")