我有一个场景,我期望会发生一些事情,但它没有,我似乎无法弄清楚为什么。我对 throw 功能还是新手,所以我在这里有点好奇。也许有人可以解释为什么会发生这种情况。
我做了这个功能:
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)")
并用“movieIDs”拼错“movieID”,这在我的CoreData模型中不存在,应用程序崩溃:
Thread 1: Exception: "keypath movieIDs not found in entity <NSSQLEntity SavedMovieAddition id=2>"
在这里,我希望它能够进入 catch block 并返回 .fetchFailed?
为什么这没有发生?但相反,应用程序崩溃了? - 我认为有一个 do-try-catch block 的全部意义在于消除这些崩溃?
有什么我想念的吗?
最佳答案
你有一些很好的解释的评论。另一件可能有用的事情是,如果可以避免它们,您可以通过不使用裸字符串来帮助避免您描述的那种错误。如果可能的话,做一些让编译器检查你是否拼错的事情。在这种情况下,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))`
关于swift - 了解 CoreData 的错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62457795/