【发布时间】:2019-10-10 12:54:12
【问题描述】:
我遇到了 CoreData 的问题。我有一个像这样的通用函数:
func fetchRequest<T : NSManagedObject>() -> NSFetchRequest<T>?
{
let entity = T.entity()
guard let entityName = entity.name else { return nil }
let request = NSFetchRequest<T>(entityName: entityName)
return request
}
没有理由它不应该工作 - 在大多数情况下它没有问题。但是,有时我的函数会返回 nil。当我调试它时,我得到了最有趣的结果:
(lldb) po entity
<uninitialized>
这很有趣,因为NSManagedObject.entity() 返回一个非可选的NSEntityDescription
没有关于何时失败的规则 - 例如,当我在循环中调用此函数 5 次时,它可以在前两次工作,然后第三次失败。也没有关于实体类的规则。
我也尝试过其他方法。
extension NSManagedObject
{
class func concreteFetchRequest<T>() -> NSFetchRequest<T>
{
let entityName = String(describing: self)
return NSFetchRequest(entityName: entityName)
}
}
大多数时候也可以,但有时
po 实体名称
NSManagedObject
尽管被具体的NSManagedObject 子类使用。当这个泛型函数被用于一系列其他泛型函数时,就会出现这个错误,就像这样
func theTop()
{
let instance : ConcreteNSManagedObjectSubclass = firstOrCreated() // "Entity description for entity name NSManagedObject not found"
}
func firstOrCreated<T: NSManagedObject>() -> T
{
let entity : T
if let existingEntities() {
// do stuff
}
// do other stuff
}
func existingEntities<T: NSManagedObject>() -> [T]?
{
guard let request : NSFetchRequest<T> = fetchRequest() else
{ return [] }
// do stuff
}
func fetchRequest<T : NSManagedObject>() -> NSFetchRequest<T>?
{
let entity = T.entity()
guard let entityName = entity.name else { return nil }
let request = NSFetchRequest<T>(entityName: entityName)
return request
}
但是,如果我修改代码以在最顶部直接从 ConcreteNSManagedObjectSubclass 创建一个 NSFetchRequest 并将其传递下去 - 它总是有效的。
func theTop()
{
let fetchRequest : NSFetchRequest<ConcreteNSManagedObjectSubclass> = ConcreteNSManagedObjectSubclass.concreteFetchRequest()
let instance : ConcreteNSManagedObjectSubclass = firstOrCreated(fetchRequest) // works fine
}
对我来说,这看起来像是一个 Swift 编译器错误,就像它无法将参数 T 解析为具体类型,所以它会退回到 NSManagedObject - 但如果是这种情况,那甚至不应该编译。还是我做错了什么?
【问题讨论】:
-
existingEntities() 在 T 上是通用的。在 firstOrCreated() 方法中,您以这种方式调用 existingEntities() 'if let existingEntities()'。在现有实体()的调用站点中,您没有提供足够的信息来解决该方法的通用“T”。里面有错别字吗?
标签: swift generics core-data nsmanagedobject