【问题标题】:Understanding error handling with CoreData了解 CoreData 的错误处理
【发布时间】:2020-10-08 23:19:22
【问题描述】:

我有一个场景,我期望某些事情会发生,但它没有,我似乎无法弄清楚为什么。我对投掷功能还是新手,所以我在这里有点好奇。也许有人可以解释为什么会这样。

我做了这个功能:

func checkExistanceOfMovieAddition(id: Int) -> Result<SavedMovieAddition, CoreDataErrors> {
    let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: SavedMovieAddition.entityName)
    request.predicate = NSPredicate(format: "movieID == \(id)")

    do {
        let fetch = try context.fetch(request)
        if let result = fetch.first as? SavedMovieAddition {
            return.success(result)
        } else {
            return.failure(.additionNotFound)
        }
    } catch {
        return.failure(.fetchFailed)
    }
}

它就像一个魅力。如果我搜索一个不存在的 id,我会得到一个空数组并返回我的自定义错误类型。但是..如果我换行:

request.predicate = NSPredicate(format: "movieID == \(id)")

并将“movieID”拼错为“movieIDs”,这在我的 CoreData 模型中不存在,导致应用崩溃:

Thread 1: Exception: "keypath movieIDs not found in entity <NSSQLEntity SavedMovieAddition id=2>"

在这里我希望它去 catch 块并返回 .fetchFailed?

为什么没有发生这种情况?但相反,应用程序崩溃了? - 我认为有一个 do-try-catch 块的全部意义在于消除这些崩溃?

我有什么遗漏吗?

【问题讨论】:

  • 啊……我明白了!谢谢你。所以它不应该跳入 catch 块。 (或者至少它不是内置的) - 我怎样才能让它失败呢?只是为了检查它是否真的有效?我的意思是,那个 do-try-catch 块会评估什么?
  • 好问题。文档说“如果执行 fetch 时出现问题”——我现在不知道如何触发它。
  • 另请注意,Swift 中的 do/catch 会捕获 错误。 无效的谓词会引发 Objective-C 异常,而这些在 Swift 中无法捕获。
  • 阿哈,我明白了! Objective-C 异常,值得阅读的新内容。再次感谢您的详细说明,非常感谢。

标签: swift core-data error-handling


【解决方案1】:

你有一些解释很好的 cmets。可能有用的另一件事是,如果可以避免它们,您可以通过不使用裸字符串来帮助避免您描述的那种错误。如果可能的话,做一些让编译器检查你是否拼错的事情。在这种情况下,Swift 键路径会有所帮助。

你有

request.predicate = NSPredicate(format: "movieID == \(id)")

...这可行,但如果您拼错该属性,则会出现问题。如果你把它写成

request.predicate = `NSPredicate(format: "\(#keyPath(SavedMovieAddition.movieID)) == \(id)")`

...编译器将检查密钥路径。如果您将其键入为movieIDs,您的代码将无法编译,并且您会收到一条错误消息,指出Type 'SavedMovieAddition' has no member 'movieIDs'。如果对您更有意义,您也可以这样写:

request.predicate = `NSPredicate(format: "%K == \(id)", #keyPath(SavedMovieAddition.movieID))`

【讨论】:

  • 真的很喜欢你的最后一行。完美运行!谢谢! - 它没有回答为什么我没有到达 Catch 块(Martin R 的答案更接近),但我会将其标记为已接受的答案,因为它可以防止在编译之前发生这种崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 2017-03-28
  • 2016-05-30
  • 2014-07-14
  • 2021-04-12
  • 1970-01-01
  • 2011-03-11
相关资源
最近更新 更多