Swift 4字符串插值警告及修复后Segue崩溃问题求助
Hey there! Let's tackle your problem step by step—first the annoying warnings, then the crash you hit after using Xcode's suggested fixes.
Why the Warnings Pop Up
Starting in Swift 4, Apple made string interpolation of optional values more explicit. When you directly plug an optional (like sender which is Any?, or segue.identifier which is String?) into a string, Swift warns you because it's quietly using the debug description (which includes stuff like Optional(...) or nil) under the hood. It wants you to intentionally choose how to handle the optional value.
Fixing the Warnings (Without Breaking Things)
Let's fix each warning line in your code with safe, clear options:
Warning in
Unexpected sender: \(sender)
You have two solid choices here:- Option 1: Use
String(describing:)to explicitly show the debug value (this is Xcode's first suggestion):fatalError("Unexpected sender: \(String(describing: sender))") - Option 2: Provide a user-friendly default value for when
senderisnil:fatalError("Unexpected sender: \(sender ?? "Unknown Sender")")
- Option 1: Use
Warning in
Unexpected Segue Identifier; \(segue.identifier)
Apply the same logic here:- Option 1: Explicitly show the debug value:
fatalError("Unexpected Segue Identifier; \(String(describing: segue.identifier))") - Option 2: Use a default value for nil identifiers:
fatalError("Unexpected Segue Identifier; \(segue.identifier ?? "Unknown Identifier")")
- Option 1: Explicitly show the debug value:
Why the Crash Happened
The crash message Thread 1: Fatal error: Unexpected Segue Identifier; has nothing to do with the String(describing:) fix—it means your app is hitting the default case in the switch statement. That tells you:
- You're triggering a segue that doesn't match either "AddItem" or "ShowDetail"
- Double-check all your segues in Interface Builder: make sure their identifiers are spelled exactly right (capitalization matters!)
- If you have an extra, unused segue, delete it. If you meant to handle another one, add a new case to the switch for its identifier.
Full Fixed Code
Here's your code with warnings fixed using String(describing:) (and the crash root cause addressed):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { super.prepare(for: segue, sender: Any?) 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)") // No warning here—segue.destination is non-optional } guard let selectedMealCell = sender as? MealTableViewCell else { fatalError("Unexpected sender: \(String(describing: 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; \(String(describing: segue.identifier))") } }
Or if you prefer using default values instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { super.prepare(for: segue, sender: Any?) 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 ?? "Unknown 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 ?? "Unknown Identifier")") } }
内容的提问来源于stack exchange,提问作者Theodor K

