手动去捕捉 do...catch 的语句

Manually go to catch statement of do...catch

我想测试数组的计数是否大于 0,否则关闭当前视图。

现在我是这样做的:

do {
    let pets = try self.managedObjectContext.fetch(request)
    guard pets.count > 0 else {
        self.dismiss(animated: true, completion: nil)
    }
    dateCreated = Date(timeIntervalSince1970: Double(pets[0].dateCreated))
} catch {
    self.dismiss(animated: true, completion: nil)
}

我想知道如果计数不大于 0,我是否可以手动将 do..catch 发送到 catch,这样我就不必 self.dismiss(animated: true, completion: nil) 写了两次。有人知道这是否可能吗?

显然您不关心 error 因此您可以使用 try? 而不是 do-catch:

guard
    let pets = try? self.managedObjectContext.fetch(request), 
    !pets.isEmpty
else {
    self.dismiss(animated: true, completion: nil)
    return 
}

dateCreated = Date(timeIntervalSince1970: Double(pets[0].dateCreated))

另一种选择是将重复的代码移动到 function/closure,例如

let onError: () -> Void = {
   self.dismiss(animated: true, completion: nil)
}

do {
    let pets = try self.managedObjectContext.fetch(request)
    guard pets.count > 0 else {
       onError()
       return
    }
    dateCreated = Date(timeIntervalSince1970: Double(pets[0].dateCreated))
} catch {
    onError()
}

如果您执着于 do 街区,您可以这样做:

struct MyError: Error { }

do {
    let pets = try self.managedObjectContext.fetch(request)
    guard pets.count > 0 else {
        throw MyError()
    }
    dateCreated = Date(timeIntervalSince1970: Double(pets[0].dateCreated))
} catch {
    self.dismiss(animated: true, completion: nil)
}

听起来您想尝试使用 defer

guard 条件没有返回。那是有问题的。

试试

defer {
    self.dismiss(animated:true, completion:nil)
}

do {
    let pets = try self.managedObjectContext.fetch(request)
    guard pets.count > 0 else {
        return
    }
    dateCreated = Date(timeIntervalSince1970: Double(pets[0].dateCreated))
} catch {
    // TODO - do any error work required if no pets.  Possibly nothing.
}

使用 defer 将保证在方法退出时调用代码行。