【问题标题】:NSManagedObject.entity() - uninitializedNSManagedObject.entity() - 未初始化
【发布时间】: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


【解决方案1】:

请替换:

let request = NSFetchRequest<T>(entityName: entityName)

与:

let request = T.Type.fetchRequest() as NSFetchRequest<T>

或

let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)

随你喜欢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2021-12-14
    • 2013-06-26
    • 2016-04-02
    • 2020-02-14
    • 2018-09-10
    相关资源
    最近更新 更多