我正在尝试为简单的核心数据提取创建一种通用的包装器。
我想要实现的目标是,而不是编写多个看起来像这样的冗余方法:
func loadNSMOSubclass() -> [NSMOSubclass] {
let fetchRequest: NSFetchRequest<NSMOSubclass> = NSMOSubclass.fetchRequest()
do {
let result = try mainContext.fetch(fetchRequest)
return result
}
catch {
return []
}
}
我以为我可以为此创建一个通用助手:
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 []
}
}
}
然而,在那时编译器有一个奇怪的错误:
无法将
NSFetchRequest<NSFetchRequestResult>
类型的值转换为指定类型NSFetchRequest<T>
建议的解决方案甚至更奇怪,因为当我进行投射时所有内容都会编译:
let fetchRequest: NSFetchRequest<T> = T.fetchRequest() as! NSFetchRequest<T>
这可能很丑,但我可以忍受。但是,当我运行此代码时,我遇到致命错误:
由于未捕获的异常而终止应用 &#39; NSInvalidArgumentException&#39;,原因:&#39; executeFetchRequest:错误:
<null>
不是有效的NSFetchRequest。&#39;
我做错了什么,或者这些只是目前无法超越的一些斯威夫特的限制?
答案 0 :(得分:0)
这里的问题是fetchRequest()
是自动生成的帮助器函数,仅对您的NSManagedObject
子类可用。它不适用于您的通用类型。因此,不必使用该函数,而必须将其实现与此类通用类型一起使用
替换此行
let fetchRequest: NSFetchRequest<T> = T.fetchRequest()
与此
let fetchRequest: NSFetchRequest<T> = NSFetchRequest<T>(entityName: String(describing: T.self))