我试图弄清楚Swift 3如何使用if let
语法处理解包。我的场景是我想在if let
语句中从CoreData进行提取。我想在那里打开值,如果有值(不是nil),那就用它吧。如果没有值,请执行else
块中的内容。似乎有意义,但根据我的经验,这不是Swift 3的想法。
注意 :没有要返回的“对象”实体。我想下拉打印“无物体”。
CODE
// How I'm making the fetch from CoreData
class func getAllObjects() -> [Object]? {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest<Object>(entityName: "Object")
let fetched = try! context.fetch(fetchRequest)
return fetched
}
// Unwrapping value: How I'd do it... But Xcode didn't like...
if let fetchedObjects = WorkOrder.getAllObjects() as? [Order] {
self.objects = fetchedObjects
}
else {
print("No Objects")
}
// Unwrapping value: How Xcode "corrected" my code and this compiles
if let fetchedObjects = WorkOrder.getAllObjects()! as [Order]? {
self.objects = fetchedObjects
}
else {
print("No Objects")
}
发生什么
该应用程序崩溃。在打开选项值时发现了nil。我认为if let
应该防止我的应用程序崩溃。因为如果没有任何有效的解包方法,它应该执行else
块。正确?
问题
您是否知道如何让if let
以我上面建议的方式行事?或将表现的代码?
答案 0 :(得分:3)
WorkOrder.getAllObjects()
将返回一个空数组,而不是nil
。由于getAllObjects
返回类型[Order]
的可选数组,因此您不需要向下转换,条件赋值就足够了。
如果您使用保护声明进行条件分配和isEmpty
测试,您的代码将更清晰:
guard let fetchedObjects = WorkOrder.getAllObjects(), !fetchedObjects.isEmpty else {
print("No Objects")
return
}
print("There are \(fetchedObjects.count) work orders") // Note, no need to unwrap as the guard statement has already done this
使用try!
getAllObjects
编写代码的方式永远不会返回nil
;它将返回Order
的一个(可能是空的)数组,否则它将崩溃。如果出现问题,您应该将getAllObjects
声明为throws
或至少返回nil
:
class func getAllObjects() -> [Object]? {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest<Object>(entityName: "Object")
var fetched: [Object]? = nil
do {
fetched = try context.fetch(fetchRequest)
}
catch() {
print("Error fetching work orders: \(error)")
}
return fetched
}