use*_*248 4 generics core-data swift
我正在尝试为简单的核心数据获取创建一种通用包装器。
我想要实现的是,而不是编写如下所示的多个冗余方法:
func loadNSMOSubclass() -> [NSMOSubclass] {
let fetchRequest: NSFetchRequest<NSMOSubclass> = NSMOSubclass.fetchRequest()
do {
let result = try mainContext.fetch(fetchRequest)
return result
}
catch {
return []
}
}
Run Code Online (Sandbox Code Playgroud)
我想我可以为此创建一个通用助手:
struct EntityLoader<T> where T: NSManagedObject {
func loadEntity() -> [T] {
let fetchRequest: NSFetchRequest<T> = T.fetchRequest()
do {
let mainContext = CoreDataState().mainContext
let result = try mainContext.fetch(fetchRequest)
return result
}
catch {
return []
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,此时编译器出现了一个奇怪的错误:
无法将类型的值转换
NSFetchRequest<NSFetchRequestResult>为指定类型NSFetchRequest<T>
建议的解决方案更奇怪,因为当我进行转换时,所有内容都会编译:
let fetchRequest: NSFetchRequest<T> = T.fetchRequest() as! NSFetchRequest<T>
Run Code Online (Sandbox Code Playgroud)
这可能很丑陋,但我可以忍受。但是,当我运行此代码时,我收到一个致命错误:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“executeFetchRequest:错误:
<null>不是有效的 NSFetchRequest。”
我是否做错了什么,或者这些只是 Swift 目前无法超越的一些限制?
这里的问题fetchRequest()是自动生成的辅助函数,它仅适用于您的NSManagedObject子类。它不适用于您的通用类型。因此,您不必使用该函数,而是必须将其实现与您的泛型类型一起使用,如下所示,
替换这一行,
let fetchRequest: NSFetchRequest<T> = T.fetchRequest()
Run Code Online (Sandbox Code Playgroud)
有了这个,
let fetchRequest: NSFetchRequest<T> = NSFetchRequest<T>(entityName: String(describing: T.self))
Run Code Online (Sandbox Code Playgroud)